Setup

Load Packages

##Install Packages if Needed
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("cowplot")) install.packages("cowplot")
if (!require("lubridate")) install.packages("lubridate")
if (!require("corrplot")) install.packages("corrplot")
if (!require("lme4")) install.packages("lme4")
if (!require("vegan")) install.packages("vegan")
if (!require("DHARMa")) install.packages("DHARMa")
if (!require("effectsize")) install.packages("effectsize")
if (!require("emmeans")) install.packages("emmeans")
if (!require("lmerTest")) install.packages("lmerTest")
if (!require("tidyr")) install.packages("tidyr")
if (!require("dplyr")) install.packages("dplyr")
if (!require("plotrix")) install.packages("plotrix")
if (!require("Rmisc")) install.packages("Rmisc")
if (!require("ggpubr")) install.packages("ggpubr")

##Load Packages
library(ggplot2) #Required for ggplots
library(cowplot) #Required for plotting panel figures
library(lubridate) #Required for date and time formatting
library(corrplot) #Required for correlation plot
library(lme4) #Required for mixed effects modeling
library(vegan) #Required for multivariate analysis PERM
library(DHARMa) #Required to check residuals of mixed effects models
library(effectsize) #Required for eta_squared effect sizes
library(emmeans) #Required for pairwise comparisons 
library(lmerTest) #Required for p values with lme4 model summaries
library(tidyr) #Required for pivot_wider function
library(dplyr) #Required for group_by function
library(plotrix) #Required for Standard error function
library(Rmisc) #Required for SummarySE function
library(ggpubr) #Required for stat brackets

Graphing Parameters

#Note: Run "Graphing Parameters" section from 01_ExperimentalSetup.Rmd file

Sample Data and Metadata

Load and Organize Data

##Growth
Length<-read.csv("Data/LengthFull.csv", header=TRUE)
Dates<-read.csv("Data/BonaireDates.csv", header=TRUE)

##Set date variables
Dates$Date<-as.Date(Dates$Date, format='%m/%d/%Y')

##Set factor variables
Length$Site<-factor(Length$Site, levels=c("KL", "SS"))
Length$Genotype<-factor(Length$Genotype, levels=c("AC8", "AC10", "AC12"))
Length$Orig<-factor(Length$Orig, levels=c("N", "T"))
Length$Origin<-factor(Length$Origin, levels=c("Native", "Transplant"))

##Add a Sample Set Variable
Length$Set<-paste(Length$Site, Length$Genotype, Length$Orig, sep=".")
Length$Set<-factor(Length$Set)

##Add Site.Orig variable
Length$Site.Orig<-paste(Length$Site, Length$Orig, sep=".")
Length$Site.Orig<-factor(Length$Site.Orig, levels=c("KL.N", "KL.T", "SS.N", "SS.T"))


##Bleaching Metrics
#Note: Physiological metrics calculated in 02_PhysiologyMetrics.R file
Thermal<-read.csv("Outputs/ThermData.csv", header=TRUE)

##Set factor variables
Thermal$TimeP<-factor(Thermal$TimeP, levels=c("IN", "TP1", "TP2", "TP3", "TP4"))
Thermal$Site<-factor(Thermal$Site, levels=c("KL", "SS"))
Thermal$Genotype<-factor(Thermal$Genotype, levels=c("AC8", "AC10", "AC12"))
Thermal$Orig<-factor(Thermal$Orig, levels=c("N", "T"))
Thermal$Origin<-factor(Thermal$Origin, levels=c("Native", "Transplant"))

Growth

Growth Rate TP1 to TP2

Calculate Days

##Subset Dates for TP 1 and TP 2 Growth
Growth.Dates_TP1.2<-subset(Dates, Task=="Growth" & TimeP=="TP1" |
                       Task=="Growth" & TimeP=="TP2" )

##Convert to Wide format
Growth.Dates_TP1.2<-Growth.Dates_TP1.2 %>%  pivot_wider(names_from = TimeP, values_from = Date)

##Calculate Number of Days
#TP 1 to TP2
Growth.Dates_TP1.2$TP1.2_days<-time_length(Growth.Dates_TP1.2$TP2-Growth.Dates_TP1.2$TP1, unit="days")

Calculate Total Linear Extension

##Merge Length Data with Growth Dates
#Merges by Site column
#Adds TP1.2_days column
Growth_TP1.2<-merge(Length, Growth.Dates_TP1.2[,c(-2)], all.x=TRUE)

##Calculate Linear Extension (cm)
Growth_TP1.2$Ext_cm<-Growth_TP1.2$TL.TP2_cm-Growth_TP1.2$TL.TP1_cm

##Calculate Growth_TP1.2 Rate (cm/day)
Growth_TP1.2$TLE_cm.day<-Growth_TP1.2$Ext_cm/Growth_TP1.2$TP1.2_days

Data QC

##Remove Corals not Measured in T1 to T2
Growth_TP1.2<-Growth_TP1.2 %>% drop_na(TLE_cm.day)

##Sample Size per Set
Growth_TP1.2 %>% 
  dplyr::group_by(Set) %>%
  dplyr::summarize(SampleSize = length(Set))

##Check for Outliers
ggplot(Growth_TP1.2, aes(x=Set, y=TLE_cm.day)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))

Potential outliers have been re-measured and therefore will be retained. n=10 per Site, Genotype, Origin group

Compare Growth Rate

#Check normality
hist(Growth_TP1.2$TLE_cm.day)

shapiro.test(Growth_TP1.2$TLE_cm.day)

    Shapiro-Wilk normality test

data:  Growth_TP1.2$TLE_cm.day
W = 0.92803, p-value = 7.262e-06
#Not normal

hist(log(Growth_TP1.2$TLE_cm.day+1))

shapiro.test(log(Growth_TP1.2$TLE_cm.day+1))

    Shapiro-Wilk normality test

data:  log(Growth_TP1.2$TLE_cm.day + 1)
W = 0.94335, p-value = 7.248e-05
##Still not normal

##Compare generalized linear mixed effects models
TLE_TP1.2.glmr.gaus<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=gaussian(link="identity"))
Warning: calling glmer() with family=gaussian (identity link) as a shortcut to lmer() is deprecated; please call lmer() directly
TLE_TP1.2.glmr.gaus.l<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=gaussian(link="log"))
TLE_TP1.2.glmr.gaus.i<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=gaussian(link="inverse"))

TLE_TP1.2.glmr.gam.l<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=Gamma(link="log"))
TLE_TP1.2.glmr.gam.i<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=Gamma(link="inverse"))

TLE_TP1.2.glmr.inv<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=inverse.gaussian(link="1/mu^2"))
boundary (singular) fit: see help('isSingular')
TLE_TP1.2.glmr.inv.l<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=inverse.gaussian(link="log"))
TLE_TP1.2.glmr.inv.i<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP1.2, family=inverse.gaussian(link="inverse"))

AIC(TLE_TP1.2.glmr.gaus, TLE_TP1.2.glmr.gaus.l, TLE_TP1.2.glmr.gaus.i, TLE_TP1.2.glmr.gam.l, TLE_TP1.2.glmr.gam.i, TLE_TP1.2.glmr.inv, TLE_TP1.2.glmr.inv.l, TLE_TP1.2.glmr.inv.i)

Gamma distribution with log-link has the lowest AIC.

##Check residuals
TLE_TP1.2.glmr.gam.l_res <- simulateResiduals(fittedModel = TLE_TP1.2.glmr.gam.l, plot = F)
plot(TLE_TP1.2.glmr.gam.l_res)

Compare residuals across models

##Check residuals
TLE_TP1.2.glmr.gaus.l_res <- simulateResiduals(fittedModel = TLE_TP1.2.glmr.gaus.l, plot = F)
plot(TLE_TP1.2.glmr.gaus.l_res)

Compare with log+1 transformed lmer model

LMER Model

##Model with log +1 transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
TLE_TP1.2.lme<-lmer(log(TLE_cm.day+1)~Origin*Site+(1|Genotype), data=Growth_TP1.2)

##Check residuals
TLE_TP1.2.lme_res <- simulateResiduals(fittedModel = TLE_TP1.2.lme, plot = F)
plot(TLE_TP1.2.lme_res)

Better residuals with the log+1 transformed lmer model.

##Model results
summary(TLE_TP1.2.lme)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: log(TLE_cm.day + 1) ~ Origin * Site + (1 | Genotype)
   Data: Growth_TP1.2

REML criterion at convergence: -233.2

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.0026 -0.5991 -0.1118  0.5959  2.4282 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.002965 0.05445 
 Residual             0.006632 0.08144 
Number of obs: 120, groups:  Genotype, 3

Fixed effects:
                          Estimate Std. Error         df t value Pr(>|t|)   
(Intercept)               0.125179   0.034778   2.684719   3.599  0.04400 * 
OriginTransplant         -0.007538   0.021027 114.000000  -0.359  0.72063   
SiteSS                    0.062096   0.021027 114.000000   2.953  0.00382 **
OriginTransplant:SiteSS  -0.035167   0.029737 114.000000  -1.183  0.23943   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.302              
SiteSS      -0.302  0.500       
OrgnTrn:SSS  0.214 -0.707 -0.707
eta_squared(TLE_TP1.2.lme)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |           0.02 | [0.00, 1.00]
Site        |           0.07 | [0.01, 1.00]
Origin:Site |           0.01 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
TLE_TP1.2.res<-data.frame(summary(TLE_TP1.2.lme)$coefficients[-1,])
TLE_TP1.2.res$Predictor<-c("Origin", "Site", "Origin x Site")
TLE_TP1.2.res$EtaSq<-c(eta_squared(TLE_TP1.2.lme)$Eta2)
TLE_TP1.2.res$Response<-rep("Growth", nrow(TLE_TP1.2.res))
TLE_TP1.2.res$Timepoint<-rep("TP1_2", nrow(TLE_TP1.2.res))

Pairwise

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
TLE.pair_TP1.2<-emmeans(TLE_TP1.2.lme, pairwise~Origin | Site)
TLE.pair_TP1.2
$emmeans
Site = KL:
 Origin     emmean     SE   df  lower.CL upper.CL
 Native      0.125 0.0348 2.68  0.006770    0.244
 Transplant  0.118 0.0348 2.68 -0.000768    0.236

Site = SS:
 Origin     emmean     SE   df  lower.CL upper.CL
 Native      0.187 0.0348 2.68  0.068866    0.306
 Transplant  0.145 0.0348 2.68  0.026161    0.263

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate    SE  df t.ratio p.value
 Native - Transplant  0.00754 0.021 114   0.359  0.7206

Site = SS:
 contrast            estimate    SE  df t.ratio p.value
 Native - Transplant  0.04271 0.021 114   2.031  0.0446

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
TLE.pair.es_TP1.2<-data.frame(eff_size(TLE.pair_TP1.2, sigma=sigma(TLE_TP1.2.lme), edf=df.residual(TLE_TP1.2.lme)))
Since 'object' is a list, we are using the contrasts already present.
TLE.pair.es_TP1.2
TLE.pair.es_TP1.2<-TLE.pair.es_TP1.2 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
TLE.pair_TP1.2.res<-merge(data.frame(TLE.pair_TP1.2$contrasts), TLE.pair.es_TP1.2[,-c(1)])
TLE.pair_TP1.2.res$Response<-rep("Growth", nrow(TLE.pair_TP1.2.res))
TLE.pair_TP1.2.res$TimeP<-rep("TP1_2", nrow(TLE.pair_TP1.2.res))

##Add Significance levels
TLE.pair_TP1.2.res$Sig<-ifelse(TLE.pair_TP1.2.res$p.value<0.001, "***",
                              ifelse(TLE.pair_TP1.2.res$p.value<0.01, "**",
                                     ifelse(TLE.pair_TP1.2.res$p.value<0.05, "*",
                                            ifelse(TLE.pair_TP1.2.res$p.value<0.1, "-", NA))))
TLE.pair_TP1.2.res

Plot Growth TP 1 to 2

##Summary statistics by Site and Origin
TP1.2_Growth.sum<-summarySE(Growth_TP1.2, measurevar="TLE_cm.day", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Growth Rate across Treatments
TP1.2_Growth.plot<-ggplot(TP1.2_Growth.sum, aes(x=Site, y=TLE_cm.day, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=TLE_cm.day-se, ymax=TLE_cm.day+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y=expression(paste('Growth Rate (cm day'^-1*")")), colour="Origin")+
  ylim(0, 0.25)+
  annotate("text", x=2, y=0.24, label="*", size=sig.sz, fontface="bold")+
  geom_bracket(xmin=1, xmax=2, y.position=0.01, label.size=levels.sz, label="**", inherit.aes = FALSE); TP1.2_Growth.plot

Percent Difference in Growth Rates

##Summary statistics by Genotype, Origin, and Site
TP1.2_Growth.sum<-summarySE(Growth_TP1.2, measurevar="TLE_cm.day", groupvars=c("Genotype", "Origin", "Site"), na.rm=TRUE)

##Calculate Percent Difference between Native and Transplant by Genotype
TP1.2_Growth.dif<-TP1.2_Growth.sum[which(TP1.2_Growth.sum$Origin=="Native"), c(1,3,5)]
TP1.2_Growth.dif<-TP1.2_Growth.dif %>% dplyr::rename(TLE_N = TLE_cm.day)
TP1.2_Growth.dif$TLE_T<-TP1.2_Growth.sum$TLE_cm.day[which(TP1.2_Growth.sum$Origin=="Transplant")]

##SS
TP1.2_Growth.dif_SS<-subset(TP1.2_Growth.dif, Site=="SS")
TP1.2_Growth.dif_SS$Perc.Inc<-((TP1.2_Growth.dif_SS$TLE_N-TP1.2_Growth.dif_SS$TLE_T)/TP1.2_Growth.dif_SS$TLE_T)*100
TP1.2_Growth.dif_SS

##Mean and Standard Error
mean(TP1.2_Growth.dif_SS$Perc.Inc)
[1] 47.19841
std.error(TP1.2_Growth.dif_SS$Perc.Inc)
[1] 25.89777
##KL
TP1.2_Growth.dif_KL<-subset(TP1.2_Growth.dif, Site=="KL")
TP1.2_Growth.dif_KL$Perc.Inc<-((TP1.2_Growth.dif_KL$TLE_N-TP1.2_Growth.dif_KL$TLE_T)/TP1.2_Growth.dif_KL$TLE_T)*100
TP1.2_Growth.dif_KL

##Mean and Standard Error
mean(TP1.2_Growth.dif_KL$Perc.Inc)
[1] 4.187086
std.error(TP1.2_Growth.dif_KL$Perc.Inc)
[1] 8.336196

Growth Rate TP3 to TP4

Calculate Days

##Subset Dates for TP 3 and TP 4 Growth
Growth.Dates_TP3.4<-subset(Dates, Task=="Growth" & TimeP=="TP3" |
                       Task=="Growth" & TimeP=="TP4" )

##Convert to Wide format
Growth.Dates_TP3.4<-Growth.Dates_TP3.4 %>%  pivot_wider(names_from = TimeP, values_from = Date)

##Calculate Number of Days
#TP 3 to TP4
Growth.Dates_TP3.4$TP3.4_days<-time_length(Growth.Dates_TP3.4$TP4-Growth.Dates_TP3.4$TP3, unit="days")

Calculate Total Linear Extension

##Merge Length Data with Growth Dates
#Merges by Site column
#Adds TP3.4_days column
Growth_TP3.4<-merge(Length, Growth.Dates_TP3.4[,c(-2)], all.x=TRUE)

##Calculate Linear Extension (cm)
Growth_TP3.4$Ext_cm<-Growth_TP3.4$TL.TP4_cm-Growth_TP3.4$TL.TP3_cm

##Calculate Growth_TP3.4 Rate (cm/day)
Growth_TP3.4$TLE_cm.day<-Growth_TP3.4$Ext_cm/Growth_TP3.4$TP3.4_days

Data QC

##Remove Corals not Measured in T1 to T2
Growth_TP3.4<-Growth_TP3.4 %>% drop_na(TLE_cm.day)

##Sample Size per Set
Growth_TP3.4 %>% 
  dplyr::group_by(Set) %>%
  dplyr::summarize(SampleSize = length(Set))

##Check for Outliers
ggplot(Growth_TP3.4, aes(x=Set, y=TLE_cm.day)) + 
  geom_boxplot(alpha=0.5, shape=2, outlier.shape = NA)+
  geom_jitter(shape=16, position=position_jitter(0.1))+
  theme(axis.text.x = element_text(angle = 90))

Compare Growth Rate

#Check normality
hist(Growth_TP3.4$TLE_cm.day)

shapiro.test(Growth_TP3.4$TLE_cm.day)

    Shapiro-Wilk normality test

data:  Growth_TP3.4$TLE_cm.day
W = 0.92767, p-value = 6.904e-06
#Not normal

hist(log(Growth_TP3.4$TLE_cm.day+1))

shapiro.test(log(Growth_TP3.4$TLE_cm.day+1))

    Shapiro-Wilk normality test

data:  log(Growth_TP3.4$TLE_cm.day + 1)
W = 0.94719, p-value = 0.0001351
##Still not normal

##Compare generalized linear mixed effects models
TLE_TP3.4.glmr.gaus<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=gaussian(link="identity"))
Warning: calling glmer() with family=gaussian (identity link) as a shortcut to lmer() is deprecated; please call lmer() directly
TLE_TP3.4.glmr.gaus.l<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=gaussian(link="log"))
TLE_TP3.4.glmr.gaus.i<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=gaussian(link="inverse"))

TLE_TP3.4.glmr.gam.l<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=Gamma(link="log"))
TLE_TP3.4.glmr.gam.i<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=Gamma(link="inverse"))

TLE_TP3.4.glmr.inv<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=inverse.gaussian(link="1/mu^2"))
TLE_TP3.4.glmr.inv.l<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=inverse.gaussian(link="log"))
TLE_TP3.4.glmr.inv.i<-glmer(TLE_cm.day~Origin*Site+(1|Genotype), data=Growth_TP3.4, family=inverse.gaussian(link="inverse"))

AIC(TLE_TP3.4.glmr.gaus, TLE_TP3.4.glmr.gaus.l, TLE_TP3.4.glmr.gaus.i, TLE_TP3.4.glmr.gam.l, TLE_TP3.4.glmr.gam.i, TLE_TP3.4.glmr.inv, TLE_TP3.4.glmr.inv.l, TLE_TP3.4.glmr.inv.i)

Gamma distribution with log-link has the lowest AIC.

##Check residuals
TLE_TP3.4.glmr.gam.l_res <- simulateResiduals(fittedModel = TLE_TP3.4.glmr.gam.l, plot = F)
plot(TLE_TP3.4.glmr.gam.l_res)

Compare residuals across models

##Check residuals
TLE_TP3.4.glmr.gaus.l_res <- simulateResiduals(fittedModel = TLE_TP3.4.glmr.gaus.l, plot = F)
plot(TLE_TP3.4.glmr.gaus.l_res)

Compare with log+1 transformed lmer model

LMER Model

##Model with log +1 transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
TLE_TP3.4.lme<-lmer(log(TLE_cm.day+1)~Origin*Site+(1|Genotype), data=Growth_TP3.4)

##Check residuals
TLE_TP3.4.lme_res <- simulateResiduals(fittedModel = TLE_TP3.4.lme, plot = F)
plot(TLE_TP3.4.lme_res)

Better residuals with the log+1 transformed lmer model.

##Model results
summary(TLE_TP3.4.lme)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: log(TLE_cm.day + 1) ~ Origin * Site + (1 | Genotype)
   Data: Growth_TP3.4

REML criterion at convergence: -341.9

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.27432 -0.60263 -0.01933  0.56722  2.45603 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.002008 0.04481 
 Residual             0.002574 0.05074 
Number of obs: 120, groups:  Genotype, 3

Fixed effects:
                         Estimate Std. Error        df t value Pr(>|t|)    
(Intercept)               0.16891    0.02748   2.38972   6.147 0.016262 *  
OriginTransplant         -0.02845    0.01310 114.00000  -2.172 0.031936 *  
SiteSS                   -0.05868    0.01310 114.00000  -4.479 1.79e-05 ***
OriginTransplant:SiteSS   0.06284    0.01853 114.00000   3.392 0.000954 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.238              
SiteSS      -0.238  0.500       
OrgnTrn:SSS  0.169 -0.707 -0.707
eta_squared(TLE_TP3.4.lme)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |       9.01e-04 | [0.00, 1.00]
Site        |           0.07 | [0.01, 1.00]
Origin:Site |           0.09 | [0.02, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
TLE_TP3.4.res<-data.frame(summary(TLE_TP3.4.lme)$coefficients[-1,])
TLE_TP3.4.res$Predictor<-c("Origin", "Site", "Origin x Site")
TLE_TP3.4.res$EtaSq<-c(eta_squared(TLE_TP3.4.lme)$Eta2)
TLE_TP3.4.res$Response<-rep("Growth", nrow(TLE_TP3.4.res))
TLE_TP3.4.res$Timepoint<-rep("TP3_4", nrow(TLE_TP3.4.res))

Pairwise

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
TLE.pair_TP3.4<-emmeans(TLE_TP3.4.lme, pairwise~Origin | Site)
TLE.pair_TP3.4
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.169 0.0275 2.39  0.06737    0.270
 Transplant  0.140 0.0275 2.39  0.03892    0.242

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.110 0.0275 2.39  0.00869    0.212
 Transplant  0.145 0.0275 2.39  0.04308    0.246

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant   0.0285 0.0131 114   2.172  0.0319

Site = SS:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant  -0.0344 0.0131 114  -2.625  0.0098

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
TLE.pair.es_TP3.4<-data.frame(eff_size(TLE.pair_TP3.4, sigma=sigma(TLE_TP3.4.lme), edf=df.residual(TLE_TP3.4.lme)))
Since 'object' is a list, we are using the contrasts already present.
TLE.pair.es_TP3.4
TLE.pair.es_TP3.4<-TLE.pair.es_TP3.4 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
TLE.pair_TP3.4.res<-merge(data.frame(TLE.pair_TP3.4$contrasts), TLE.pair.es_TP3.4[,-c(1)])
TLE.pair_TP3.4.res$Response<-rep("Growth", nrow(TLE.pair_TP3.4.res))
TLE.pair_TP3.4.res$TimeP<-rep("TP3_4", nrow(TLE.pair_TP3.4.res))

##Add Significance levels
TLE.pair_TP3.4.res$Sig<-ifelse(TLE.pair_TP3.4.res$p.value<0.001, "***",
                              ifelse(TLE.pair_TP3.4.res$p.value<0.01, "**",
                                     ifelse(TLE.pair_TP3.4.res$p.value<0.05, "*",
                                            ifelse(TLE.pair_TP3.4.res$p.value<0.1, "-", NA))))
TLE.pair_TP3.4.res

Plot Growth TP 3 to 4

##Summary statistics by Site and Origin
TP3.4_Growth.sum<-summarySE(Growth_TP3.4, measurevar="TLE_cm.day", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Growth Rate across Treatments
TP3.4_Growth.plot<-ggplot(TP3.4_Growth.sum, aes(x=Site, y=TLE_cm.day, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=TLE_cm.day-se, ymax=TLE_cm.day+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y=expression(paste('Growth Rate (cm day'^-1*")")), colour="Origin")+
  ylim(0, 0.25)+
  annotate("text", x=1, y=0.22, label="*", size=sig.sz, fontface="bold")+
  annotate("text", x=2, y=0.18, label="**", size=sig.sz, fontface="bold")+
  geom_bracket(xmin=1, xmax=2, y.position=0.01, label.size=levels.sz, label="***", inherit.aes = FALSE); TP3.4_Growth.plot

Percent Difference in Growth Rates

##Summary statistics by Genotype, Origin, and Site
TP3.4_Growth.sum<-summarySE(Growth_TP3.4, measurevar="TLE_cm.day", groupvars=c("Genotype", "Origin", "Site"), na.rm=TRUE)

##Calculate Percent Difference between Native and Transplant by Genotype
TP3.4_Growth.dif<-TP3.4_Growth.sum[which(TP3.4_Growth.sum$Origin=="Native"), c(1,3,5)]
TP3.4_Growth.dif<-TP3.4_Growth.dif %>% dplyr::rename(TLE_N = TLE_cm.day)
TP3.4_Growth.dif$TLE_T<-TP3.4_Growth.sum$TLE_cm.day[which(TP3.4_Growth.sum$Origin=="Transplant")]

##SS
TP3.4_Growth.dif_SS<-subset(TP3.4_Growth.dif, Site=="SS")
TP3.4_Growth.dif_SS$Perc.Inc<-((TP3.4_Growth.dif_SS$TLE_T-TP3.4_Growth.dif_SS$TLE_N)/TP3.4_Growth.dif_SS$TLE_N)*100
TP3.4_Growth.dif_SS

##Mean and Standard Error
mean(TP3.4_Growth.dif_SS$Perc.Inc)
[1] 34.22395
std.error(TP3.4_Growth.dif_SS$Perc.Inc)
[1] 18.61694
##KL
TP3.4_Growth.dif_KL<-subset(TP3.4_Growth.dif, Site=="KL")
TP3.4_Growth.dif_KL$Perc.Inc<-((TP3.4_Growth.dif_KL$TLE_N-TP3.4_Growth.dif_KL$TLE_T)/TP3.4_Growth.dif_KL$TLE_T)*100
TP3.4_Growth.dif_KL

##Mean and Standard Error
mean(TP3.4_Growth.dif_KL$Perc.Inc)
[1] 21.37099
std.error(TP3.4_Growth.dif_KL$Perc.Inc)
[1] 4.101183

Write Out Growth Data

##Growth Data dataframe
GrowthData<-Growth_TP1.2

##Specify Timepoints
GrowthData<-GrowthData %>% dplyr::rename(TP1.2_Ext_cm = Ext_cm, TP1.2_TLE_cm.day = TLE_cm.day)

##Merge with Timepoints 3 to 4
GrowthData<-merge(GrowthData, Growth_TP3.4, all=TRUE)

##Specify Timepoints
GrowthData<-GrowthData %>% dplyr::rename(TP3.4_Ext_cm = Ext_cm, TP3.4_TLE_cm.day = TLE_cm.day)

##Growth Data
write.csv(GrowthData, "Outputs/GrowthData.csv", row.names=FALSE)

Thermal Tolerance

Percent Retention

Subset Thermal Assay Data by Treatment

##Control
Therm_C<-subset(Thermal, Treat=="C")

##Heated
Therm_H<-subset(Thermal, Treat=="H")

Calculate Percent Retention

Calculating retention as proportion remaining relative to corresponding control levels (0-1) for each site and genotype at each timepoint.

##Calculate averages for Control Treatment for each Site, Genotype, and Timepoint 
Therm_C<-na.omit(Therm_C)
names(Therm_C)
 [1] "ID"          "RandN"       "TimeP"       "Site"        "Genotype"    "Treat"      
 [7] "Treatment"   "Orig"        "Origin"      "Set"         "Site.Orig"   "SA_cm2"     
[13] "Chl_ug.cm2"  "Sym10.6_cm2" "Fv_Fm"      
Therm_C.a<-aggregate(Therm_C[,c(13:15)], list(Therm_C$Site, Therm_C$Genotype, Therm_C$TimeP, Therm_C$Origin), mean, na.action = na.omit)
names(Therm_C.a)[1:4]<-c("Site", "Genotype", "TimeP", "Origin")
names(Therm_C.a)[5:7]<-paste(names(Therm_C.a)[5:7], "C", sep="_")

##Merge Control Averages with Heated Samples
#Merges by Site, Genotype, and Timepoint
Therm_H<-merge(Therm_H, Therm_C.a, all.x=TRUE )

##Calculate Proportion Retained for each Bleaching Metric relative to Control
Therm_H$Chl.prop<-round((Therm_H$Chl_ug.cm2/Therm_H$Chl_ug.cm2_C), 4)
Therm_H$Sym.prop<-round((Therm_H$Sym10.6_cm2/Therm_H$Sym10.6_cm2_C), 4)
Therm_H$PAM.prop<-round((Therm_H$Fv_Fm/Therm_H$Fv_Fm_C), 4)

##Set values >1 to 1
Therm_H$Chl.prop[which(Therm_H$Chl.prop>1)]<-1.0000
Therm_H$Sym.prop[which(Therm_H$Sym.prop>1)]<-1.0000
Therm_H$PAM.prop[which(Therm_H$PAM.prop>1)]<-1.0000

Initial Heat Assay

##Subset Initial Timepoint
Thermal_IN<-subset(Thermal, TimeP=="IN")
Thermal_IN$Site.Treat<-paste(Thermal_IN$Site, Thermal_IN$Treat, sep=".")
Thermal_IN$Site.Treat<-factor(Thermal_IN$Site.Treat, levels=c("KL.C", "KL.H", "SS.C", "SS.H"))


Therm_IN<-subset(Therm_H, TimeP=="IN")

Heated vs Control

Symbionts

#Check normality
hist(Thermal_IN$Sym10.6_cm2)

shapiro.test(Thermal_IN$Sym10.6_cm2)

    Shapiro-Wilk normality test

data:  Thermal_IN$Sym10.6_cm2
W = 0.90824, p-value = 0.001334
#Not normal

hist(log(Thermal_IN$Sym10.6_cm2+1))

shapiro.test(log(Thermal_IN$Sym10.6_cm2+1))

    Shapiro-Wilk normality test

data:  log(Thermal_IN$Sym10.6_cm2 + 1)
W = 0.95667, p-value = 0.07936
#Normal

##Model
#Function of Site and Treatment, with Genotype as a Random effect
Sym.lme_IN<-lmer(log(Sym10.6_cm2+1)~Site*Treatment+(1|Genotype), data=Thermal_IN)

##Check residuals
Sym.lme_res_IN <- simulateResiduals(fittedModel = Sym.lme_IN, plot = F)
plot(Sym.lme_res_IN)


##Model results
summary(Sym.lme_IN)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: log(Sym10.6_cm2 + 1) ~ Site * Treatment + (1 | Genotype)
   Data: Thermal_IN

REML criterion at convergence: -29.3

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-1.79325 -0.66013  0.08255  0.57806  2.12486 

Random effects:
 Groups   Name        Variance  Std.Dev.
 Genotype (Intercept) 0.0008222 0.02867 
 Residual             0.0230525 0.15183 
Number of obs: 47, groups:  Genotype, 3

Fixed effects:
                     Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)           0.38823    0.04685 14.06727   8.286 8.77e-07 ***
SiteSS                0.19508    0.06198 41.00308   3.147  0.00307 ** 
TreatmentHeat        -0.20370    0.06340 41.10985  -3.213  0.00256 ** 
SiteSS:TreatmentHeat -0.01724    0.08867 41.05799  -0.194  0.84677    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) SiteSS TrtmnH
SiteSS      -0.661              
TreatmentHt -0.647  0.489       
StSS:TrtmnH  0.462 -0.699 -0.715
eta_squared(Sym.lme_IN)
# Effect Size for ANOVA (Type III)

Parameter      | Eta2 (partial) |       95% CI
----------------------------------------------
Site           |           0.30 | [0.12, 1.00]
Treatment      |           0.36 | [0.17, 1.00]
Site:Treatment |       9.20e-04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
emmeans(Sym.lme_IN, pairwise ~ Site | Treatment)
$emmeans
Treatment = Control:
 Site emmean     SE   df lower.CL upper.CL
 KL    0.388 0.0469 14.1   0.2878    0.489
 SS    0.583 0.0469 14.1   0.4829    0.684

Treatment = Heat:
 Site emmean     SE   df lower.CL upper.CL
 KL    0.185 0.0488 15.6   0.0808    0.288
 SS    0.362 0.0469 14.1   0.2619    0.463

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Treatment = Control:
 contrast estimate     SE   df t.ratio p.value
 KL - SS    -0.195 0.0620 41.0  -3.147  0.0031

Treatment = Heat:
 contrast estimate     SE   df t.ratio p.value
 KL - SS    -0.178 0.0635 41.1  -2.801  0.0077

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
emmeans(Sym.lme_IN, pairwise ~ Treatment | Site)
$emmeans
Site = KL:
 Treatment emmean     SE   df lower.CL upper.CL
 Control    0.388 0.0469 14.1   0.2878    0.489
 Heat       0.185 0.0488 15.6   0.0808    0.288

Site = SS:
 Treatment emmean     SE   df lower.CL upper.CL
 Control    0.583 0.0469 14.1   0.4829    0.684
 Heat       0.362 0.0469 14.1   0.2619    0.463

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast       estimate     SE   df t.ratio p.value
 Control - Heat    0.204 0.0635 41.1   3.209  0.0026

Site = SS:
 contrast       estimate     SE   df t.ratio p.value
 Control - Heat    0.221 0.0620 41.0   3.564  0.0009

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
##Save model results
Sym_IN.res<-data.frame(summary(Sym.lme_IN)$coefficients[-1,])

##Add pairwise
names(Sym_IN.res)<-names(data.frame(emmeans(Sym.lme_IN, pairwise ~ Site | Treatment)$contrasts))[-c(1:2)]
Sym_IN.res<-rbind(Sym_IN.res,
data.frame(rbind(emmeans(Sym.lme_IN, pairwise ~ Site | Treatment)$contrasts[1], emmeans(Sym.lme_IN, pairwise ~ Site | Treatment)$contrasts[2], emmeans(Sym.lme_IN, pairwise ~ Treatment | Site)$contrasts[1], emmeans(Sym.lme_IN, pairwise ~ Treatment | Site)$contrasts[2]))[,-c(1:3)])

##Metadata
Sym_IN.res$Predictor<-c("Site", "Treatment", "Site x Treatment", "Control Site", "Heated Site", "KL Treatment", "SS Treatment")
Sym_IN.res$Response<-rep("Symbionts", nrow(Sym_IN.res))
Sym_IN.res$EtaSq<-c(eta_squared(Sym.lme_IN)$Eta2, rep(NA, 4))
##Summary statistics by Site
IN_Sym.sum<-summarySE(Thermal_IN, measurevar="Sym10.6_cm2", groupvars=c("Site", "Treatment", "Site.Treat"), na.rm=TRUE)

##Plot Average Symbionts across Treatments
IN_Sym.plot<-ggplot(IN_Sym.sum, aes(x=Site.Treat, y=Sym10.6_cm2, colour=Site)) + 
  scale_colour_manual(values=Site.colors.o)+
  geom_errorbar(aes(ymin=Sym10.6_cm2-se, ymax=Sym10.6_cm2+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(aes(shape=Treatment), size=point.sz, position=position_dodge(width=0.5))+
  scale_shape_manual(values=c(1,16))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Treatment", y=expression(paste('Symbiont Density ('*10^6,'cells cm'^-2*")")), colour="Site")+
  ylim(0, 1)+
  annotate("text", x=.6, y=1, hjust=0, label="Site **", size=sig.sz, fontface="bold")+
  annotate("text", x=.6, y=.94, hjust=0, label="Treatment **", size=sig.sz, fontface="bold"); IN_Sym.plot

Chlorophyll

#Check normality
hist(Thermal_IN$Chl_ug.cm2)

shapiro.test(Thermal_IN$Chl_ug.cm2)

    Shapiro-Wilk normality test

data:  Thermal_IN$Chl_ug.cm2
W = 0.88059, p-value = 0.0002132
#Not normal

hist(log(Thermal_IN$Chl_ug.cm2+1))

shapiro.test(log(Thermal_IN$Chl_ug.cm2+1))

    Shapiro-Wilk normality test

data:  log(Thermal_IN$Chl_ug.cm2 + 1)
W = 0.92511, p-value = 0.005653
#Still not normal but less skewed

##Model
#Function of Site and Treatment, with Genotype as a Random effect
Chl.lme_IN<-lmer(log(Chl_ug.cm2+1)~Site*Treatment+(1|Genotype), data=Thermal_IN)

##Check residuals
Chl.lme_res_IN <- simulateResiduals(fittedModel = Chl.lme_IN, plot = F)
plot(Chl.lme_res_IN)


##Model results
summary(Chl.lme_IN)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: log(Chl_ug.cm2 + 1) ~ Site * Treatment + (1 | Genotype)
   Data: Thermal_IN

REML criterion at convergence: -69.1

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.50589 -0.51517  0.07352  0.50169  2.35158 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.006137 0.07834 
 Residual             0.007930 0.08905 
Number of obs: 46, groups:  Genotype, 3

Fixed effects:
                     Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)           0.45648    0.05202  2.95779   8.774  0.00329 ** 
SiteSS                0.27810    0.03635 39.99255   7.650 2.38e-09 ***
TreatmentHeat        -0.37295    0.03721 40.00578 -10.024 1.80e-12 ***
SiteSS:TreatmentHeat -0.16117    0.05265 40.01278  -3.061  0.00393 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) SiteSS TrtmnH
SiteSS      -0.349              
TreatmentHt -0.341  0.489       
StSS:TrtmnH  0.241 -0.691 -0.707
eta_squared(Chl.lme_IN)
# Effect Size for ANOVA (Type III)

Parameter      | Eta2 (partial) |       95% CI
----------------------------------------------
Site           |           0.58 | [0.41, 1.00]
Treatment      |           0.88 | [0.82, 1.00]
Site:Treatment |           0.19 | [0.04, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
emmeans(Chl.lme_IN, pairwise ~ Site | Treatment)
$emmeans
Treatment = Control:
 Site emmean     SE   df lower.CL upper.CL
 KL   0.4565 0.0520 2.97   0.2899    0.623
 SS   0.7346 0.0520 2.97   0.5680    0.901

Treatment = Heat:
 Site emmean     SE   df lower.CL upper.CL
 KL   0.0835 0.0526 3.11  -0.0808    0.248
 SS   0.2005 0.0526 3.11   0.0361    0.365

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Treatment = Control:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.278 0.0364 40  -7.650  <.0001

Treatment = Heat:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.117 0.0381 40  -3.070  0.0038

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
emmeans(Chl.lme_IN, pairwise ~ Treatment | Site)
$emmeans
Site = KL:
 Treatment emmean     SE   df lower.CL upper.CL
 Control   0.4565 0.0520 2.97   0.2899    0.623
 Heat      0.0835 0.0526 3.11  -0.0808    0.248

Site = SS:
 Treatment emmean     SE   df lower.CL upper.CL
 Control   0.7346 0.0520 2.97   0.5680    0.901
 Heat      0.2005 0.0526 3.11   0.0361    0.365

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast       estimate     SE df t.ratio p.value
 Control - Heat    0.373 0.0372 40  10.022  <.0001

Site = SS:
 contrast       estimate     SE df t.ratio p.value
 Control - Heat    0.534 0.0372 40  14.353  <.0001

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
##Save model results
Chl_IN.res<-data.frame(summary(Chl.lme_IN)$coefficients[-1,])

##Add pairwise
names(Chl_IN.res)<-names(data.frame(emmeans(Chl.lme_IN, pairwise ~ Site | Treatment)$contrasts))[-c(1:2)]
Chl_IN.res<-rbind(Chl_IN.res,
data.frame(rbind(emmeans(Chl.lme_IN, pairwise ~ Site | Treatment)$contrasts[1], emmeans(Chl.lme_IN, pairwise ~ Site | Treatment)$contrasts[2], emmeans(Chl.lme_IN, pairwise ~ Treatment | Site)$contrasts[1], emmeans(Chl.lme_IN, pairwise ~ Treatment | Site)$contrasts[2]))[,-c(1:3)])

##Metadata
Chl_IN.res$Predictor<-c("Site", "Treatment", "Site x Treatment", "Control Site", "Heated Site", "KL Treatment", "SS Treatment")
Chl_IN.res$Response<-rep("Chlorophyll", nrow(Chl_IN.res))
Chl_IN.res$EtaSq<-c(eta_squared(Chl.lme_IN)$Eta2, rep(NA, 4))
##Summary statistics by Site
IN_Chl.sum<-summarySE(Thermal_IN, measurevar="Chl_ug.cm2", groupvars=c("Site", "Treatment", "Site.Treat"), na.rm=TRUE)

##Plot Average Chlorophyll across Treatments
IN_Chl.plot<-ggplot(IN_Chl.sum, aes(x=Site.Treat, y=Chl_ug.cm2, colour=Site)) + 
  scale_colour_manual(values=Site.colors.o)+
  geom_errorbar(aes(ymin=Chl_ug.cm2-se, ymax=Chl_ug.cm2+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(aes(shape=Treatment), size=point.sz, position=position_dodge(width=0.5))+
  scale_shape_manual(values=c(1,16))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Treatment", y=expression(paste('Total Chlorophyll (\u03BCg cm'^-2*")")), colour="Site")+
  ylim(0, 1.25)+
  annotate("text", x=.6, y=1.2, hjust=0, label="Site ***", size=sig.sz, fontface="bold")+
  annotate("text", x=.6, y=1.12, hjust=0, label="Treatment ***", size=sig.sz, fontface="bold")+
  annotate("text", x=.6, y=1.04, hjust=0, label="Site x Treatment **", size=sig.sz, fontface="bold"); IN_Chl.plot

FvFm

#Check normality
hist(Thermal_IN$Fv_Fm)

shapiro.test(Thermal_IN$Fv_Fm)

    Shapiro-Wilk normality test

data:  Thermal_IN$Fv_Fm
W = 0.87006, p-value = 9.097e-05
#Not normal

hist(Thermal_IN$Fv_Fm^2)

shapiro.test(Thermal_IN$Fv_Fm^2)

    Shapiro-Wilk normality test

data:  Thermal_IN$Fv_Fm^2
W = 0.90968, p-value = 0.001489
#Still not normal but less skewed

##Model
#Function of Site and Treatment, with Genotype as a Random effect
PAM.lme_IN<-lmer(Fv_Fm^2~Site*Treatment+(1|Genotype), data=Thermal_IN)
boundary (singular) fit: see help('isSingular')
##Check residuals
PAM.lme_res_IN <- simulateResiduals(fittedModel = PAM.lme_IN, plot = F)
plot(PAM.lme_res_IN)


##Model results
summary(PAM.lme_IN)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Fv_Fm^2 ~ Site * Treatment + (1 | Genotype)
   Data: Thermal_IN

REML criterion at convergence: -156.1

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.2454 -0.5025  0.1248  0.7046  1.5447 

Random effects:
 Groups   Name        Variance  Std.Dev. 
 Genotype (Intercept) 8.057e-21 8.976e-11
 Residual             1.235e-03 3.514e-02
Number of obs: 47, groups:  Genotype, 3

Fixed effects:
                     Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)           0.38027    0.01015 43.00000  37.482  < 2e-16 ***
SiteSS                0.02899    0.01435 43.00000   2.021   0.0496 *  
TreatmentHeat        -0.07814    0.01467 43.00000  -5.327 3.45e-06 ***
SiteSS:TreatmentHeat  0.03376    0.02052 43.00000   1.645   0.1072    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) SiteSS TrtmnH
SiteSS      -0.707              
TreatmentHt -0.692  0.489       
StSS:TrtmnH  0.494 -0.699 -0.715
optimizer (nloptwrap) convergence code: 0 (OK)
boundary (singular) fit: see help('isSingular')
eta_squared(PAM.lme_IN)
# Effect Size for ANOVA (Type III)

Parameter      | Eta2 (partial) |       95% CI
----------------------------------------------
Site           |           0.32 | [0.14, 1.00]
Treatment      |           0.45 | [0.27, 1.00]
Site:Treatment |           0.06 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
emmeans(PAM.lme_IN, pairwise ~ Site | Treatment)
$emmeans
Treatment = Control:
 Site emmean     SE   df lower.CL upper.CL
 KL    0.380 0.0101 21.6    0.359    0.401
 SS    0.409 0.0101 21.6    0.388    0.430

Treatment = Heat:
 Site emmean     SE   df lower.CL upper.CL
 KL    0.302 0.0106 23.5    0.280    0.324
 SS    0.365 0.0101 21.6    0.344    0.386

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Treatment = Control:
 contrast estimate     SE   df t.ratio p.value
 KL - SS   -0.0290 0.0143 41.0  -2.021  0.0499

Treatment = Heat:
 contrast estimate     SE   df t.ratio p.value
 KL - SS   -0.0627 0.0147 41.2  -4.268  0.0001

Degrees-of-freedom method: kenward-roger 
emmeans(PAM.lme_IN, pairwise ~ Treatment | Site)
$emmeans
Site = KL:
 Treatment emmean     SE   df lower.CL upper.CL
 Control    0.380 0.0101 21.6    0.359    0.401
 Heat       0.302 0.0106 23.5    0.280    0.324

Site = SS:
 Treatment emmean     SE   df lower.CL upper.CL
 Control    0.409 0.0101 21.6    0.388    0.430
 Heat       0.365 0.0101 21.6    0.344    0.386

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast       estimate     SE   df t.ratio p.value
 Control - Heat   0.0781 0.0147 41.2   5.316  <.0001

Site = SS:
 contrast       estimate     SE   df t.ratio p.value
 Control - Heat   0.0444 0.0143 41.0   3.094  0.0036

Degrees-of-freedom method: kenward-roger 
##Save model results
PAM_IN.res<-data.frame(summary(PAM.lme_IN)$coefficients[-1,])

##Add pairwise
names(PAM_IN.res)<-names(data.frame(emmeans(PAM.lme_IN, pairwise ~ Site | Treatment)$contrasts))[-c(1:2)]
PAM_IN.res<-rbind(PAM_IN.res,
data.frame(rbind(emmeans(PAM.lme_IN, pairwise ~ Site | Treatment)$contrasts[1], emmeans(PAM.lme_IN, pairwise ~ Site | Treatment)$contrasts[2], emmeans(PAM.lme_IN, pairwise ~ Treatment | Site)$contrasts[1], emmeans(PAM.lme_IN, pairwise ~ Treatment | Site)$contrasts[2]))[,-c(1:3)])

##Metadata
PAM_IN.res$Predictor<-c("Site", "Treatment", "Site x Treatment", "Control Site", "Heated Site", "KL Treatment", "SS Treatment")
PAM_IN.res$Response<-rep("FvFm", nrow(PAM_IN.res))
PAM_IN.res$EtaSq<-c(eta_squared(PAM.lme_IN)$Eta2, rep(NA, 4))

Not normal, but model residuals are OK.

##Summary statistics by Site
IN_PAM.sum<-summarySE(Thermal_IN, measurevar="Fv_Fm", groupvars=c("Site", "Treatment", "Site.Treat"), na.rm=TRUE)

##Plot Average FvFm across Treatments
IN_PAM.plot<-ggplot(IN_PAM.sum, aes(x=Site.Treat, y=Fv_Fm, colour=Site)) + 
  scale_colour_manual(values=Site.colors.o)+
  geom_errorbar(aes(ymin=Fv_Fm-se, ymax=Fv_Fm+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(aes(shape=Treatment), size=point.sz, position=position_dodge(width=0.5))+
  scale_shape_manual(values=c(1,16))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Treatment", y="Photochemical Efficiency (Fv/Fm)", colour="Site")+
  ylim(0.5, 0.655)+
  annotate("text", x=.6, y=.655, hjust=0, label="Site *", size=sig.sz, fontface="bold")+
  annotate("text", x=.6, y=.645, hjust=0, label="Treatment ***", size=sig.sz, fontface="bold"); IN_PAM.plot

Retention by Site

Symbionts

#Check normality
hist(Therm_IN$Sym.prop)

shapiro.test(Therm_IN$Sym.prop)

    Shapiro-Wilk normality test

data:  Therm_IN$Sym.prop
W = 0.93042, p-value = 0.1117
#Normal

##Model
#Function of Site, with Genotype as a Random effect
Tol_Sym.lme_IN<-lmer(Sym.prop~Site+(1|Genotype), data=Therm_IN)

##Check residuals
Tol_Sym.lme_res_IN <- simulateResiduals(fittedModel = Tol_Sym.lme_IN, plot = F)
plot(Tol_Sym.lme_res_IN)


##Model results
summary(Tol_Sym.lme_IN)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Sym.prop ~ Site + (1 | Genotype)
   Data: Therm_IN

REML criterion at convergence: -2.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-1.6802 -0.6578 -0.1521  0.6805  1.9852 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.07818  0.2796  
 Residual             0.03039  0.1743  
Number of obs: 23, groups:  Genotype, 3

Fixed effects:
            Estimate Std. Error       df t value Pr(>|t|)  
(Intercept)  0.46139    0.16983  2.21175   2.717   0.1014  
SiteSS       0.14316    0.07291 19.00328   1.964   0.0644 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
       (Intr)
SiteSS -0.225
eta_squared(Tol_Sym.lme_IN)
# Effect Size for ANOVA (Type III)

Parameter | Eta2 (partial) |       95% CI
-----------------------------------------
Site      |           0.17 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_IN.res<-data.frame(summary(Tol_Sym.lme_IN)$coefficients)
names(Tol_Sym_IN.res)<-names(Sym_IN.res)[1:5]
Tol_Sym_IN.res$Predictor<-rep("Site", nrow(Tol_Sym_IN.res))
Tol_Sym_IN.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym_IN.res))
Tol_Sym_IN.res$EtaSq<-c(eta_squared(Tol_Sym.lme_IN)$Eta2)

##Combine results
Sym_IN.res<-rbind(Sym_IN.res, Tol_Sym_IN.res[2,])
##Summary statistics by Site
IN_TolSym.sum<-summarySE(Therm_IN, measurevar="Sym.prop", groupvars=c("Site"), na.rm=TRUE)

##Plot Average Symbiont Retention across Treatments
IN_TolSym.plot<-ggplot(IN_TolSym.sum, aes(x=Site, y=Sym.prop, colour=Site)) + 
  scale_colour_manual(values=Site.colors.o)+
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site", y="Symbiont Retention", colour="Site")+
  ylim(0, 1)+
  annotate("text", x=1.5, y=0.75, label="-", size=sig.sz, fontface="bold"); IN_TolSym.plot

Chlorophyll

#Check normality
hist(Therm_IN$Chl.prop)

shapiro.test(Therm_IN$Chl.prop)

    Shapiro-Wilk normality test

data:  Therm_IN$Chl.prop
W = 0.98432, p-value = 0.9694
#Normal

##Model
#Function of Site, with Genotype as a Random effect
Tol_Chl.lme_IN<-lmer(Chl.prop~Site+(1|Genotype), data=Therm_IN)

##Check residuals
Tol_Chl.lme_res_IN <- simulateResiduals(fittedModel = Tol_Chl.lme_IN, plot = F)
plot(Tol_Chl.lme_res_IN)


##Model results
summary(Tol_Chl.lme_IN)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Chl.prop ~ Site + (1 | Genotype)
   Data: Therm_IN

REML criterion at convergence: -47.2

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-1.3909 -0.5550 -0.1823  0.5284  1.9947 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.004576 0.06765 
 Residual             0.003436 0.05861 
Number of obs: 22, groups:  Genotype, 3

Fixed effects:
            Estimate Std. Error       df t value Pr(>|t|)  
(Intercept)  0.16552    0.04290  2.40867   3.858    0.045 *
SiteSS       0.04306    0.02514 18.06310   1.713    0.104  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
       (Intr)
SiteSS -0.293
eta_squared(Tol_Chl.lme_IN)
# Effect Size for ANOVA (Type III)

Parameter | Eta2 (partial) |       95% CI
-----------------------------------------
Site      |           0.14 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_IN.res<-data.frame(summary(Tol_Chl.lme_IN)$coefficients)
names(Tol_Chl_IN.res)<-names(Chl_IN.res)[1:5]
Tol_Chl_IN.res$Predictor<-rep("Site", nrow(Tol_Chl_IN.res))
Tol_Chl_IN.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl_IN.res))
Tol_Chl_IN.res$EtaSq<-c(eta_squared(Tol_Chl.lme_IN)$Eta2)

##Combine results
Chl_IN.res<-rbind(Chl_IN.res, Tol_Chl_IN.res[2,])
##Summary statistics by Site and Origin
IN_TolChl.sum<-summarySE(Therm_IN, measurevar="Chl.prop", groupvars=c("Site"), na.rm=TRUE)

##Plot Average Chlorophyll Retention across Treatments
IN_TolChl.plot<-ggplot(IN_TolChl.sum, aes(x=Site, y=Chl.prop, colour=Site)) + 
  scale_colour_manual(values=Site.colors.o)+
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site", y="Chlorophyll Retention", colour="Site")+
  ylim(0, 0.35); IN_TolChl.plot

FvFm

#Check normality
hist(Therm_IN$PAM.prop)

shapiro.test(Therm_IN$PAM.prop)

    Shapiro-Wilk normality test

data:  Therm_IN$PAM.prop
W = 0.8289, p-value = 0.001154
#Not normal

hist(Therm_IN$PAM.prop^2)

shapiro.test(Therm_IN$PAM.prop^2)

    Shapiro-Wilk normality test

data:  Therm_IN$PAM.prop^2
W = 0.86491, p-value = 0.005132
##Still not normal

##Model
#Function of Site, with Genotype as a Random effect
Tol_PAM.lme_IN<-lmer(PAM.prop~Site+(1|Genotype), data=Therm_IN)

##Check residuals
Tol_PAM.lme_res_IN <- simulateResiduals(fittedModel = Tol_PAM.lme_IN, plot = F)
plot(Tol_PAM.lme_res_IN)


##Model results
summary(Tol_PAM.lme_IN)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: PAM.prop ~ Site + (1 | Genotype)
   Data: Therm_IN

REML criterion at convergence: -50.5

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.7860 -0.2498  0.1225  0.5362  1.4591 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.002221 0.04713 
 Residual             0.003538 0.05948 
Number of obs: 23, groups:  Genotype, 3

Fixed effects:
            Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)  0.89138    0.03262  2.77551  27.325 0.000185 ***
SiteSS       0.05230    0.02487 19.00103   2.103 0.049053 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
       (Intr)
SiteSS -0.399
eta_squared(Tol_PAM.lme_IN)
# Effect Size for ANOVA (Type III)

Parameter | Eta2 (partial) |       95% CI
-----------------------------------------
Site      |           0.19 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_PAM_IN.res<-data.frame(summary(Tol_PAM.lme_IN)$coefficients)
names(Tol_PAM_IN.res)<-names(PAM_IN.res)[1:5]
Tol_PAM_IN.res$Predictor<-rep("Site", nrow(Tol_PAM_IN.res))
Tol_PAM_IN.res$Response<-rep("FvFm Retention", nrow(Tol_PAM_IN.res))
Tol_PAM_IN.res$EtaSq<-c(eta_squared(Tol_PAM.lme_IN)$Eta2)

##Combine results
PAM_IN.res<-rbind(PAM_IN.res, Tol_PAM_IN.res[2,])

Not normal, but model residuals are OK.

##Summary statistics by Site and Origin
IN_TolPAM.sum<-summarySE(Therm_IN, measurevar="PAM.prop", groupvars=c("Site"), na.rm=TRUE)

##Plot Average FvFm Retention across Treatments
IN_TolPAM.plot<-ggplot(IN_TolPAM.sum, aes(x=Site, y=PAM.prop, colour=Site)) + 
  scale_colour_manual(values=Site.colors.o)+
  geom_errorbar(aes(ymin=PAM.prop-se, ymax=PAM.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site", y="Photochemical Efficiency Retention", colour="Site")+
  ylim(0.6, 1)+
  annotate("text", x=1.5, y=1, label="*", size=sig.sz, fontface="bold"); IN_TolPAM.plot

Tolerance after Transplant

TP1

##Subset Timepoint 1
Therm_TP1<-subset(Therm_H, TimeP=="TP1")

Symbionts

#Check normality
hist(Therm_TP1$Sym.prop)

shapiro.test(Therm_TP1$Sym.prop)

    Shapiro-Wilk normality test

data:  Therm_TP1$Sym.prop
W = 0.91699, p-value = 0.002332
#Not normal

hist(log(Therm_TP1$Sym.prop+1))

shapiro.test(log(Therm_TP1$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(Therm_TP1$Sym.prop + 1)
W = 0.92258, p-value = 0.003671
##Still not normal 

##Model with no transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_Sym.lme_TP1<-lmer(Sym.prop~Origin*Site+(1|Genotype), data=Therm_TP1)

##Check residuals
Tol_Sym.lme_res_TP1 <- simulateResiduals(fittedModel = Tol_Sym.lme_TP1, plot = F)
plot(Tol_Sym.lme_res_TP1)


##Model results
summary(Tol_Sym.lme_TP1)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Sym.prop ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP1

REML criterion at convergence: -3.1

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.2276 -0.5910 -0.0696  0.7547  1.8547 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.07291  0.2700  
 Residual             0.03714  0.1927  
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)  
(Intercept)              0.35578    0.16552  2.38641   2.149   0.1436  
OriginTransplant         0.14490    0.07867 42.00000   1.842   0.0726 .
SiteSS                   0.06829    0.07867 42.00000   0.868   0.3903  
OriginTransplant:SiteSS -0.15161    0.11126 42.00000  -1.363   0.1803  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.238              
SiteSS      -0.238  0.500       
OrgnTrn:SSS  0.168 -0.707 -0.707
eta_squared(Tol_Sym.lme_TP1)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |           0.04 | [0.00, 1.00]
Site        |       4.34e-04 | [0.00, 1.00]
Origin:Site |           0.04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_TP1.res<-data.frame(summary(Tol_Sym.lme_TP1)$coefficients[-1,])
Tol_Sym_TP1.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_Sym_TP1.res$EtaSq<-c(eta_squared(Tol_Sym.lme_TP1)$Eta2)
Tol_Sym_TP1.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym_TP1.res))

Not normal, but model residuals are OK.

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Sym.pair_TP1<-emmeans(Tol_Sym.lme_TP1, pairwise~Origin | Site)
Tol_Sym.pair_TP1
$emmeans
Site = KL:
 Origin     emmean    SE   df lower.CL upper.CL
 Native      0.356 0.166 2.39   -0.257    0.968
 Transplant  0.501 0.166 2.39   -0.112    1.113

Site = SS:
 Origin     emmean    SE   df lower.CL upper.CL
 Native      0.424 0.166 2.39   -0.188    1.036
 Transplant  0.417 0.166 2.39   -0.195    1.030

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant -0.14490 0.0787 42  -1.842  0.0726

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  0.00671 0.0787 42   0.085  0.9325

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Sym.pair.es_TP1<-data.frame(eff_size(Tol_Sym.pair_TP1, sigma=sigma(Tol_Sym.lme_TP1), edf=df.residual(Tol_Sym.lme_TP1)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Sym.pair.es_TP1
Tol_Sym.pair.es_TP1<-Tol_Sym.pair.es_TP1 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Sym.pair_TP1.res<-merge(data.frame(Tol_Sym.pair_TP1$contrasts), Tol_Sym.pair.es_TP1[,-c(1)])
Tol_Sym.pair_TP1.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym.pair_TP1.res))

##Add Significance levels
Tol_Sym.pair_TP1.res$Sig<-ifelse(Tol_Sym.pair_TP1.res$p.value<0.001, "***",
                              ifelse(Tol_Sym.pair_TP1.res$p.value<0.01, "**",
                                     ifelse(Tol_Sym.pair_TP1.res$p.value<0.05, "*",
                                            ifelse(Tol_Sym.pair_TP1.res$p.value<0.1, "-", NA))))
Tol_Sym.pair_TP1.res
##Summary statistics by Site and Origin
TP1_TolSym.sum<-summarySE(Therm_TP1, measurevar="Sym.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Symbiont Retention across Treatments
TP1_TolSym.plot<-ggplot(TP1_TolSym.sum, aes(x=Site, y=Sym.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Symbiont Retention", colour="Origin")+
  ylim(0, 1)+
  annotate("text", x=1, y=0.65, label="-", size=sig.sz, fontface="bold"); TP1_TolSym.plot

Chlorophyll

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site and Timepoint
Tol_Chl.pair<-emmeans(Tol_Chl.lme, pairwise~Origin | Site*TimeP)
Tol_Chl.pair
$emmeans
Site = KL, TimeP = TP1:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.1556 0.0408 41.3  0.07319    0.238
 Transplant 0.1697 0.0408 41.3  0.08727    0.252

Site = SS, TimeP = TP1:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.1849 0.0408 41.3  0.10249    0.267
 Transplant 0.1726 0.0408 41.3  0.09010    0.255

Site = KL, TimeP = TP2:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.3108 0.0408 41.3  0.22832    0.393
 Transplant 0.2723 0.0408 41.3  0.18988    0.355

Site = SS, TimeP = TP2:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.2456 0.0408 41.3  0.16318    0.328
 Transplant 0.2688 0.0408 41.3  0.18639    0.351

Site = KL, TimeP = TP3:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.5549 0.0408 41.3  0.47243    0.637
 Transplant 0.6116 0.0408 41.3  0.52910    0.694

Site = SS, TimeP = TP3:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.6275 0.0408 41.3  0.54508    0.710
 Transplant 0.6382 0.0408 41.3  0.55573    0.721

Site = KL, TimeP = TP4:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.1000 0.0408 41.3  0.01759    0.182
 Transplant 0.0858 0.0408 41.3  0.00330    0.168

Site = SS, TimeP = TP4:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.0723 0.0424 46.5 -0.01305    0.158
 Transplant 0.0895 0.0408 41.3  0.00707    0.172

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL, TimeP = TP1:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant  -0.0141 0.0533 173  -0.264  0.7919

Site = SS, TimeP = TP1:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant   0.0124 0.0533 173   0.233  0.8163

Site = KL, TimeP = TP2:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant   0.0384 0.0533 173   0.722  0.4715

Site = SS, TimeP = TP2:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant  -0.0232 0.0533 173  -0.436  0.6635

Site = KL, TimeP = TP3:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant  -0.0567 0.0533 173  -1.064  0.2889

Site = SS, TimeP = TP3:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant  -0.0107 0.0533 173  -0.200  0.8417

Site = KL, TimeP = TP4:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant   0.0143 0.0533 173   0.268  0.7888

Site = SS, TimeP = TP4:
 contrast            estimate     SE  df t.ratio p.value
 Native - Transplant  -0.0172 0.0545 173  -0.316  0.7523

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Chl.pair.es<-data.frame(eff_size(Tol_Chl.pair, sigma=sigma(Tol_Chl.lme), edf=df.residual(Tol_Chl.lme)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Chl.pair.es
Tol_Chl.pair.es<-Tol_Chl.pair.es %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Chl.pair.res<-merge(data.frame(Tol_Chl.pair$contrasts), Tol_Chl.pair.es[,-c(1)])
Tol_Chl.pair.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl.pair.res))

Not normal, but model residuals are OK.

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Chl.pair_TP1<-emmeans(Tol_Chl.lme_TP1, pairwise~Origin | Site)
Tol_Chl.pair_TP1
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.156 0.0657 2.27  -0.0970    0.408
 Transplant  0.170 0.0657 2.27  -0.0829    0.422

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.185 0.0657 2.27  -0.0677    0.438
 Transplant  0.173 0.0657 2.27  -0.0801    0.425

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  -0.0141 0.0266 42  -0.529  0.5997

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant   0.0124 0.0266 42   0.466  0.6439

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Chl.pair.es_TP1<-data.frame(eff_size(Tol_Chl.pair_TP1, sigma=sigma(Tol_Chl.lme_TP1), edf=df.residual(Tol_Chl.lme_TP1)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Chl.pair.es_TP1
Tol_Chl.pair.es_TP1<-Tol_Chl.pair.es_TP1 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Chl.pair_TP1.res<-merge(data.frame(Tol_Chl.pair_TP1$contrasts), Tol_Chl.pair.es_TP1[,-c(1)])
Tol_Chl.pair_TP1.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl.pair_TP1.res))

##Add Significance levels
Tol_Chl.pair_TP1.res$Sig<-ifelse(Tol_Chl.pair_TP1.res$p.value<0.001, "***",
                              ifelse(Tol_Chl.pair_TP1.res$p.value<0.01, "**",
                                     ifelse(Tol_Chl.pair_TP1.res$p.value<0.05, "*",
                                            ifelse(Tol_Chl.pair_TP1.res$p.value<0.1, "-", NA))))
Tol_Chl.pair_TP1.res
##Summary statistics by Site and Origin
TP1_TolChl.sum<-summarySE(Therm_TP1, measurevar="Chl.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Chlorophyll Retention across Treatments
TP1_TolChl.plot<-ggplot(TP1_TolChl.sum, aes(x=Site, y=Chl.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Chlorophyll Retention", colour="Origin")+
  ylim(0, 0.35); TP1_TolChl.plot

FvFm

#Check normality
hist(Therm_TP1$PAM.prop)

shapiro.test(Therm_TP1$PAM.prop)

    Shapiro-Wilk normality test

data:  Therm_TP1$PAM.prop
W = 0.84073, p-value = 1.245e-05
#Not normal

hist(Therm_TP1$PAM.prop^2)

shapiro.test(Therm_TP1$PAM.prop^2)

    Shapiro-Wilk normality test

data:  Therm_TP1$PAM.prop^2
W = 0.88155, p-value = 0.0001681
##Still not normal

##Model with no transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_PAM.lme_TP1<-lmer(PAM.prop~Origin*Site+(1|Genotype), data=Therm_TP1)

##Check residuals
Tol_PAM.lme_res_TP1 <- simulateResiduals(fittedModel = Tol_PAM.lme_TP1, plot = F)
plot(Tol_PAM.lme_res_TP1)


##Model results
summary(Tol_PAM.lme_TP1)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: PAM.prop ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP1

REML criterion at convergence: -84.6

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.3058 -0.3498  0.1733  0.6717  1.7818 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.002735 0.05230 
 Residual             0.006214 0.07883 
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)              0.86181    0.03781  3.74555  22.794 3.72e-05 ***
OriginTransplant         0.06813    0.03218 42.00000   2.117   0.0402 *  
SiteSS                  -0.01277    0.03218 42.00000  -0.397   0.6936    
OriginTransplant:SiteSS -0.07942    0.04551 42.00000  -1.745   0.0883 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.426              
SiteSS      -0.426  0.500       
OrgnTrn:SSS  0.301 -0.707 -0.707
eta_squared(Tol_PAM.lme_TP1)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |           0.04 | [0.00, 1.00]
Site        |           0.11 | [0.01, 1.00]
Origin:Site |           0.07 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_PAM_TP1.res<-data.frame(summary(Tol_PAM.lme_TP1)$coefficients[-1,])
Tol_PAM_TP1.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_PAM_TP1.res$EtaSq<-c(eta_squared(Tol_PAM.lme_TP1)$Eta2)
Tol_PAM_TP1.res$Response<-rep("FvFm Retention", nrow(Tol_PAM_TP1.res))

Not normal, but model residuals are OK.

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_PAM.pair_TP1<-emmeans(Tol_PAM.lme_TP1, pairwise~Origin | Site)
Tol_PAM.pair_TP1
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.862 0.0378 3.75    0.754    0.970
 Transplant  0.930 0.0378 3.75    0.822    1.038

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.849 0.0378 3.75    0.741    0.957
 Transplant  0.838 0.0378 3.75    0.730    0.946

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  -0.0681 0.0322 42  -2.117  0.0402

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant   0.0113 0.0322 42   0.351  0.7276

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_PAM.pair.es_TP1<-data.frame(eff_size(Tol_PAM.pair_TP1, sigma=sigma(Tol_PAM.lme_TP1), edf=df.residual(Tol_PAM.lme_TP1)))
Since 'object' is a list, we are using the contrasts already present.
Tol_PAM.pair.es_TP1
Tol_PAM.pair.es_TP1<-Tol_PAM.pair.es_TP1 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_PAM.pair_TP1.res<-merge(data.frame(Tol_PAM.pair_TP1$contrasts), Tol_PAM.pair.es_TP1[,-c(1)])
Tol_PAM.pair_TP1.res$Response<-rep("FvFm Retention", nrow(Tol_PAM.pair_TP1.res))

##Add Significance levels
Tol_PAM.pair_TP1.res$Sig<-ifelse(Tol_PAM.pair_TP1.res$p.value<0.001, "***",
                              ifelse(Tol_PAM.pair_TP1.res$p.value<0.01, "**",
                                     ifelse(Tol_PAM.pair_TP1.res$p.value<0.05, "*",
                                            ifelse(Tol_PAM.pair_TP1.res$p.value<0.1, "-", NA))))
Tol_PAM.pair_TP1.res
##Summary statistics by Site and Origin
TP1_TolPAM.sum<-summarySE(Therm_TP1, measurevar="PAM.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average FvFm Retention across Treatments
TP1_TolPAM.plot<-ggplot(TP1_TolPAM.sum, aes(x=Site, y=PAM.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=PAM.prop-se, ymax=PAM.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Photochemical Efficiency Retention", colour="Origin")+
  ylim(0.6, 1)+
  annotate("text", x=1, y=.96, label="*", size=sig.sz, fontface="bold"); TP1_TolPAM.plot

Save Results

##Combine Results
Tol_TP1.res<-rbind(Tol_PAM_TP1.res, Tol_Sym_TP1.res, Tol_Chl_TP1.res) 
Tol.pair.res_TP1<-rbind(Tol_PAM.pair_TP1.res, Tol_Sym.pair_TP1.res, Tol_Chl.pair_TP1.res)

##Add Timepoint
Tol_TP1.res$TimeP<-rep("TP1", nrow(Tol_TP1.res))
Tol.pair.res_TP1$TimeP<-rep("TP1", nrow(Tol.pair.res_TP1))

TP2

##Subset Timepoint 2
Therm_TP2<-subset(Therm_H, TimeP=="TP2")

Symbionts

#Check normality
hist(Therm_TP2$Sym.prop)

shapiro.test(Therm_TP2$Sym.prop)

    Shapiro-Wilk normality test

data:  Therm_TP2$Sym.prop
W = 0.89527, p-value = 0.0004439
#Not normal

hist(Therm_TP2$Sym.prop^2)

shapiro.test(Therm_TP2$Sym.prop^2)

    Shapiro-Wilk normality test

data:  Therm_TP2$Sym.prop^2
W = 0.8757, p-value = 0.0001129
##Still not normal

##Model with no transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_Sym.lme_TP2<-lmer(Sym.prop~Origin*Site+(1|Genotype), data=Therm_TP2)

##Check residuals
Tol_Sym.lme_res_TP2 <- simulateResiduals(fittedModel = Tol_Sym.lme_TP2, plot = F)
plot(Tol_Sym.lme_res_TP2)


##Model results
summary(Tol_Sym.lme_TP2)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Sym.prop ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP2

REML criterion at convergence: -3.4

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.20381 -0.54227  0.01202  0.47665  2.09092 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.04681  0.2164  
 Residual             0.03767  0.1941  
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                         Estimate Std. Error        df t value Pr(>|t|)  
(Intercept)              0.805833   0.136905  2.613359   5.886   0.0142 *
OriginTransplant        -0.107900   0.079237 42.000000  -1.362   0.1805  
SiteSS                  -0.178425   0.079237 42.000000  -2.252   0.0296 *
OriginTransplant:SiteSS  0.005183   0.112058 42.000000   0.046   0.9633  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.289              
SiteSS      -0.289  0.500       
OrgnTrn:SSS  0.205 -0.707 -0.707
eta_squared(Tol_Sym.lme_TP2)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |           0.08 | [0.00, 1.00]
Site        |           0.19 | [0.04, 1.00]
Origin:Site |       5.09e-05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_TP2.res<-data.frame(summary(Tol_Sym.lme_TP2)$coefficients[-1,])
Tol_Sym_TP2.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_Sym_TP2.res$EtaSq<-c(eta_squared(Tol_Sym.lme_TP2)$Eta2)
Tol_Sym_TP2.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym_TP2.res))

Not normal, but model residuals are OK.

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Sym.pair_TP2<-emmeans(Tol_Sym.lme_TP2, pairwise~Origin | Site)
Tol_Sym.pair_TP2
$emmeans
Site = KL:
 Origin     emmean    SE   df lower.CL upper.CL
 Native      0.806 0.137 2.61   0.3313    1.280
 Transplant  0.698 0.137 2.61   0.2234    1.172

Site = SS:
 Origin     emmean    SE   df lower.CL upper.CL
 Native      0.627 0.137 2.61   0.1529    1.102
 Transplant  0.525 0.137 2.61   0.0502    0.999

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant    0.108 0.0792 42   1.362  0.1805

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant    0.103 0.0792 42   1.296  0.2019

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Sym.pair.es_TP2<-data.frame(eff_size(Tol_Sym.pair_TP2, sigma=sigma(Tol_Sym.lme_TP2), edf=df.residual(Tol_Sym.lme_TP2)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Sym.pair.es_TP2
Tol_Sym.pair.es_TP2<-Tol_Sym.pair.es_TP2 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Sym.pair_TP2.res<-merge(data.frame(Tol_Sym.pair_TP2$contrasts), Tol_Sym.pair.es_TP2[,-c(1)])
Tol_Sym.pair_TP2.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym.pair_TP2.res))

##Add Significance levels
Tol_Sym.pair_TP2.res$Sig<-ifelse(Tol_Sym.pair_TP2.res$p.value<0.001, "***",
                              ifelse(Tol_Sym.pair_TP2.res$p.value<0.01, "**",
                                     ifelse(Tol_Sym.pair_TP2.res$p.value<0.05, "*",
                                            ifelse(Tol_Sym.pair_TP2.res$p.value<0.1, "-", NA))))
Tol_Sym.pair_TP2.res
##Summary statistics by Site and Origin
TP2_TolSym.sum<-summarySE(Therm_TP2, measurevar="Sym.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP2_TolSym.plot<-ggplot(TP2_TolSym.sum, aes(x=Site, y=Sym.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Symbiont Retention", colour="Origin")+
  ylim(0, 1)+
 geom_bracket(xmin=1, xmax=2, y.position=.04, label.size=levels.sz, label="*", inherit.aes = FALSE); TP2_TolSym.plot

Chlorophyll

#Check normality
hist(Therm_TP2$Chl.prop)

shapiro.test(Therm_TP2$Chl.prop)

    Shapiro-Wilk normality test

data:  Therm_TP2$Chl.prop
W = 0.97677, p-value = 0.4523
#Normal

##Model
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_Chl.lme_TP2<-lmer(Chl.prop~Origin*Site+(1|Genotype), data=Therm_TP2)

##Check residuals
Tol_Chl.lme_res_TP2 <- simulateResiduals(fittedModel = Tol_Chl.lme_TP2, plot = F)
plot(Tol_Chl.lme_res_TP2)


##Model results
summary(Tol_Chl.lme_TP2)
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: Chl.prop ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP2

REML criterion at convergence: -81

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.0024 -0.7622 -0.1174  0.6824  2.9666 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.006146 0.07840 
 Residual             0.006538 0.08086 
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)  
(Intercept)              0.31077    0.05093  2.81331   6.102   0.0106 *
OriginTransplant        -0.03844    0.03301 42.00000  -1.165   0.2508  
SiteSS                  -0.06514    0.03301 42.00000  -1.973   0.0550 .
OriginTransplant:SiteSS  0.06166    0.04668 42.00000   1.321   0.1937  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.324              
SiteSS      -0.324  0.500       
OrgnTrn:SSS  0.229 -0.707 -0.707
eta_squared(Tol_Chl.lme_TP2)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |       2.53e-03 | [0.00, 1.00]
Site        |           0.05 | [0.00, 1.00]
Origin:Site |           0.04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_TP2.res<-data.frame(summary(Tol_Chl.lme_TP2)$coefficients[-1,])
Tol_Chl_TP2.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_Chl_TP2.res$EtaSq<-c(eta_squared(Tol_Chl.lme_TP2)$Eta2)
Tol_Chl_TP2.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl_TP2.res))
##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Chl.pair_TP2<-emmeans(Tol_Chl.lme_TP2, pairwise~Origin | Site)
Tol_Chl.pair_TP2
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.311 0.0509 2.81   0.1424    0.479
 Transplant  0.272 0.0509 2.81   0.1040    0.441

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.246 0.0509 2.81   0.0773    0.414
 Transplant  0.269 0.0509 2.81   0.1005    0.437

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate    SE df t.ratio p.value
 Native - Transplant   0.0384 0.033 42   1.165  0.2508

Site = SS:
 contrast            estimate    SE df t.ratio p.value
 Native - Transplant  -0.0232 0.033 42  -0.703  0.4857

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Chl.pair.es_TP2<-data.frame(eff_size(Tol_Chl.pair_TP2, sigma=sigma(Tol_Chl.lme_TP2), edf=df.residual(Tol_Chl.lme_TP2)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Chl.pair.es_TP2
Tol_Chl.pair.es_TP2<-Tol_Chl.pair.es_TP2 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Chl.pair_TP2.res<-merge(data.frame(Tol_Chl.pair_TP2$contrasts), Tol_Chl.pair.es_TP2[,-c(1)])
Tol_Chl.pair_TP2.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl.pair_TP2.res))

##Add Significance levels
Tol_Chl.pair_TP2.res$Sig<-ifelse(Tol_Chl.pair_TP2.res$p.value<0.001, "***",
                              ifelse(Tol_Chl.pair_TP2.res$p.value<0.01, "**",
                                     ifelse(Tol_Chl.pair_TP2.res$p.value<0.05, "*",
                                            ifelse(Tol_Chl.pair_TP2.res$p.value<0.1, "-", NA))))
Tol_Chl.pair_TP2.res
##Summary statistics by Site and Origin
TP2_TolChl.sum<-summarySE(Therm_TP2, measurevar="Chl.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP2_TolChl.plot<-ggplot(TP2_TolChl.sum, aes(x=Site, y=Chl.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Chlorophyll Retention", colour="Origin")+
  ylim(0, 0.35)+
  geom_bracket(xmin=1, xmax=2, y.position=.02, label.size=levels.sz, label="-", inherit.aes = FALSE); TP2_TolChl.plot

FvFm

#Check normality
hist(Therm_TP2$PAM.prop)

shapiro.test(Therm_TP2$PAM.prop)

    Shapiro-Wilk normality test

data:  Therm_TP2$PAM.prop
W = 0.73527, p-value = 5.896e-08
#Not normal

hist(Therm_TP2$PAM.prop^2)

shapiro.test(Therm_TP2$PAM.prop^2)

    Shapiro-Wilk normality test

data:  Therm_TP2$PAM.prop^2
W = 0.80435, p-value = 1.633e-06
##Still not normal

##Model
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_PAM.lme_TP2<-lmer(PAM.prop~Origin*Site+(1|Genotype), data=Therm_TP2)

##Check residuals
Tol_PAM.lme_res_TP2 <- simulateResiduals(fittedModel = Tol_PAM.lme_TP2, plot = F)
plot(Tol_PAM.lme_res_TP2)


##Model results
summary(Tol_PAM.lme_TP2)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: PAM.prop ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP2

REML criterion at convergence: -102.1

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.8326 -0.3753 -0.0042  0.5350  1.7496 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.001675 0.04093 
 Residual             0.004192 0.06475 
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)              0.85622    0.03013  3.92146  28.419 1.09e-05 ***
OriginTransplant         0.07526    0.02643 42.00000   2.847  0.00680 ** 
SiteSS                   0.06487    0.02643 42.00000   2.454  0.01834 *  
OriginTransplant:SiteSS -0.10206    0.03738 42.00000  -2.730  0.00921 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.439              
SiteSS      -0.439  0.500       
OrgnTrn:SSS  0.310 -0.707 -0.707
eta_squared(Tol_PAM.lme_TP2)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |           0.04 | [0.00, 1.00]
Site        |           0.01 | [0.00, 1.00]
Origin:Site |           0.15 | [0.02, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_PAM_TP2.res<-data.frame(summary(Tol_PAM.lme_TP2)$coefficients[-1,])
Tol_PAM_TP2.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_PAM_TP2.res$EtaSq<-c(eta_squared(Tol_PAM.lme_TP2)$Eta2)
Tol_PAM_TP2.res$Response<-rep("FvFm Retention", nrow(Tol_PAM_TP2.res))

Not normal, but model residuals are OK.

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_PAM.pair_TP2<-emmeans(Tol_PAM.lme_TP2, pairwise~Origin | Site)
Tol_PAM.pair_TP2
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.856 0.0301 3.92    0.772    0.941
 Transplant  0.931 0.0301 3.92    0.847    1.016

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.921 0.0301 3.92    0.837    1.005
 Transplant  0.894 0.0301 3.92    0.810    0.979

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  -0.0753 0.0264 42  -2.847  0.0068

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant   0.0268 0.0264 42   1.014  0.3164

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_PAM.pair.es_TP2<-data.frame(eff_size(Tol_PAM.pair_TP2, sigma=sigma(Tol_PAM.lme_TP2), edf=df.residual(Tol_PAM.lme_TP2)))
Since 'object' is a list, we are using the contrasts already present.
Tol_PAM.pair.es_TP2
Tol_PAM.pair.es_TP2<-Tol_PAM.pair.es_TP2 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_PAM.pair_TP2.res<-merge(data.frame(Tol_PAM.pair_TP2$contrasts), Tol_PAM.pair.es_TP2[,-c(1)])
Tol_PAM.pair_TP2.res$Response<-rep("FvFm Retention", nrow(Tol_PAM.pair_TP2.res))

##Add Significance levels
Tol_PAM.pair_TP2.res$Sig<-ifelse(Tol_PAM.pair_TP2.res$p.value<0.001, "***",
                              ifelse(Tol_PAM.pair_TP2.res$p.value<0.01, "**",
                                     ifelse(Tol_PAM.pair_TP2.res$p.value<0.05, "*",
                                            ifelse(Tol_PAM.pair_TP2.res$p.value<0.1, "-", NA))))
Tol_PAM.pair_TP2.res

Save Results

##Combine Results
Tol_TP2.res<-rbind(Tol_PAM_TP2.res, Tol_Sym_TP2.res, Tol_Chl_TP2.res)
Tol.pair.res_TP2<-rbind(Tol_PAM.pair_TP2.res, Tol_Sym.pair_TP2.res, Tol_Chl.pair_TP2.res)

##Add Timepoint
Tol_TP2.res$TimeP<-rep("TP2", nrow(Tol_TP2.res))
Tol.pair.res_TP2$TimeP<-rep("TP2", nrow(Tol.pair.res_TP2))

TP3

##Subset Timepoint 3
Therm_TP3<-subset(Therm_H, TimeP=="TP3")

Symbionts

#Check normality
hist(Therm_TP3$Sym.prop)

shapiro.test(Therm_TP3$Sym.prop)

    Shapiro-Wilk normality test

data:  Therm_TP3$Sym.prop
W = 0.78653, p-value = 6.531e-07
#Not normal

hist(Therm_TP3$Sym.prop^2)

shapiro.test(Therm_TP3$Sym.prop^2)

    Shapiro-Wilk normality test

data:  Therm_TP3$Sym.prop^2
W = 0.78554, p-value = 6.213e-07
##Still not normal but less skewed

##Model with no transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_Sym.lme_TP3<-lmer(Sym.prop~Origin*Site+(1|Genotype), data=Therm_TP3)

##Check residuals
Tol_Sym.lme_res_TP3 <- simulateResiduals(fittedModel = Tol_Sym.lme_TP3, plot = F)
plot(Tol_Sym.lme_res_TP3)


##Model results
summary(Tol_Sym.lme_TP3)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Sym.prop ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP3

REML criterion at convergence: -54.7

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.1418 -0.5595  0.3785  0.6079  1.6260 

Random effects:
 Groups   Name        Variance  Std.Dev.
 Genotype (Intercept) 0.0003012 0.01735 
 Residual             0.0132967 0.11531 
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)              0.82201    0.03476 16.65879  23.646 2.98e-14 ***
OriginTransplant         0.07462    0.04708 42.00000   1.585   0.1204    
SiteSS                   0.10814    0.04708 42.00000   2.297   0.0267 *  
OriginTransplant:SiteSS -0.05670    0.06658 42.00000  -0.852   0.3992    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.677              
SiteSS      -0.677  0.500       
OrgnTrn:SSS  0.479 -0.707 -0.707
eta_squared(Tol_Sym.lme_TP3)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |           0.04 | [0.00, 1.00]
Site        |           0.12 | [0.01, 1.00]
Origin:Site |           0.02 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_TP3.res<-data.frame(summary(Tol_Sym.lme_TP3)$coefficients[-1,])
Tol_Sym_TP3.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_Sym_TP3.res$EtaSq<-c(eta_squared(Tol_Sym.lme_TP3)$Eta2)
Tol_Sym_TP3.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym_TP3.res))

Not normal, but model residuals are OK.

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Sym.pair_TP3<-emmeans(Tol_Sym.lme_TP3, pairwise~Origin | Site)
Tol_Sym.pair_TP3
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.822 0.0348 16.7    0.749    0.895
 Transplant  0.897 0.0348 16.7    0.823    0.970

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.930 0.0348 16.7    0.857    1.004
 Transplant  0.948 0.0348 16.7    0.875    1.022

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  -0.0746 0.0471 42  -1.585  0.1204

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  -0.0179 0.0471 42  -0.381  0.7053

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Sym.pair.es_TP3<-data.frame(eff_size(Tol_Sym.pair_TP3, sigma=sigma(Tol_Sym.lme_TP3), edf=df.residual(Tol_Sym.lme_TP3)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Sym.pair.es_TP3
Tol_Sym.pair.es_TP3<-Tol_Sym.pair.es_TP3 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Sym.pair_TP3.res<-merge(data.frame(Tol_Sym.pair_TP3$contrasts), Tol_Sym.pair.es_TP3[,-c(1)])
Tol_Sym.pair_TP3.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym.pair_TP3.res))

##Add Significance levels
Tol_Sym.pair_TP3.res$Sig<-ifelse(Tol_Sym.pair_TP3.res$p.value<0.001, "***",
                              ifelse(Tol_Sym.pair_TP3.res$p.value<0.01, "**",
                                     ifelse(Tol_Sym.pair_TP3.res$p.value<0.05, "*",
                                            ifelse(Tol_Sym.pair_TP3.res$p.value<0.1, "-", NA))))
Tol_Sym.pair_TP3.res
##Summary statistics by Site and Origin
TP3_TolSym.sum<-summarySE(Therm_TP3, measurevar="Sym.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP3_TolSym.plot<-ggplot(TP3_TolSym.sum, aes(x=Site, y=Sym.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Symbiont Retention", colour="Origin")+
  ylim(0, 1)+
 geom_bracket(xmin=1, xmax=2, y.position=.04, label.size=levels.sz, label="*", inherit.aes = FALSE); TP3_TolSym.plot

Chlorophyll

#Check normality
hist(Therm_TP3$Chl.prop)

shapiro.test(Therm_TP3$Chl.prop)

    Shapiro-Wilk normality test

data:  Therm_TP3$Chl.prop
W = 0.89534, p-value = 0.0004461
#Not normal

hist(log(Therm_TP3$Chl.prop+1))

shapiro.test(log(Therm_TP3$Chl.prop+1))

    Shapiro-Wilk normality test

data:  log(Therm_TP3$Chl.prop + 1)
W = 0.9211, p-value = 0.003251
##Still not normal but less skewed

##Model with log +1 transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_Chl.lme_TP3<-lmer(log(Chl.prop+1)~Origin*Site+(1|Genotype), data=Therm_TP3)
boundary (singular) fit: see help('isSingular')
##Check residuals
Tol_Chl.lme_res_TP3 <- simulateResiduals(fittedModel = Tol_Chl.lme_TP3, plot = F)
plot(Tol_Chl.lme_res_TP3)


##Model results
summary(Tol_Chl.lme_TP3)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: log(Chl.prop + 1) ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP3

REML criterion at convergence: -47.3

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-1.7095 -0.6080 -0.1405  0.4999  1.7650 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.00000  0.0000  
 Residual             0.01594  0.1262  
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)              0.43851    0.03644 44.00000  12.032 1.65e-15 ***
OriginTransplant         0.03181    0.05154 44.00000   0.617    0.540    
SiteSS                   0.03852    0.05154 44.00000   0.747    0.459    
OriginTransplant:SiteSS -0.02511    0.07289 44.00000  -0.344    0.732    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.707              
SiteSS      -0.707  0.500       
OrgnTrn:SSS  0.500 -0.707 -0.707
optimizer (nloptwrap) convergence code: 0 (OK)
boundary (singular) fit: see help('isSingular')
eta_squared(Tol_Chl.lme_TP3)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |       6.31e-03 | [0.00, 1.00]
Site        |           0.01 | [0.00, 1.00]
Origin:Site |       2.69e-03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_TP3.res<-data.frame(summary(Tol_Chl.lme_TP3)$coefficients[-1,])
Tol_Chl_TP3.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_Chl_TP3.res$EtaSq<-c(eta_squared(Tol_Chl.lme_TP3)$Eta2)
Tol_Chl_TP3.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl_TP3.res))

Not normal, but model residuals are OK.

##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Chl.pair_TP3<-emmeans(Tol_Chl.lme_TP3, pairwise~Origin | Site)
Tol_Chl.pair_TP3
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.439 0.0364 22.4    0.363    0.514
 Transplant  0.470 0.0364 22.4    0.395    0.546

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.477 0.0364 22.4    0.402    0.553
 Transplant  0.484 0.0364 22.4    0.408    0.559

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant -0.03181 0.0515 42  -0.617  0.5404

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant -0.00671 0.0515 42  -0.130  0.8971

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Chl.pair.es_TP3<-data.frame(eff_size(Tol_Chl.pair_TP3, sigma=sigma(Tol_Chl.lme_TP3), edf=df.residual(Tol_Chl.lme_TP3)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Chl.pair.es_TP3
Tol_Chl.pair.es_TP3<-Tol_Chl.pair.es_TP3 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Chl.pair_TP3.res<-merge(data.frame(Tol_Chl.pair_TP3$contrasts), Tol_Chl.pair.es_TP3[,-c(1)])
Tol_Chl.pair_TP3.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl.pair_TP3.res))

##Add Significance levels
Tol_Chl.pair_TP3.res$Sig<-ifelse(Tol_Chl.pair_TP3.res$p.value<0.001, "***",
                              ifelse(Tol_Chl.pair_TP3.res$p.value<0.01, "**",
                                     ifelse(Tol_Chl.pair_TP3.res$p.value<0.05, "*",
                                            ifelse(Tol_Chl.pair_TP3.res$p.value<0.1, "-", NA))))
Tol_Chl.pair_TP3.res
##Summary statistics by Site and Origin
TP3_TolChl.sum<-summarySE(Therm_TP3, measurevar="Chl.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP3_TolChl.plot<-ggplot(TP3_TolChl.sum, aes(x=Site, y=Chl.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Chlorophyll Retention", colour="Origin")+
  ylim(0, 1); TP3_TolChl.plot

FvFm

#Check normality
hist(Therm_TP3$PAM.prop)

shapiro.test(Therm_TP3$PAM.prop)

    Shapiro-Wilk normality test

data:  Therm_TP3$PAM.prop
W = 0.96358, p-value = 0.1408
#Normal

##Model
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_PAM.lme_TP3<-lmer(PAM.prop~Origin*Site+(1|Genotype), data=Therm_TP3)

##Check residuals
Tol_PAM.lme_res_TP3 <- simulateResiduals(fittedModel = Tol_PAM.lme_TP3, plot = F)
plot(Tol_PAM.lme_res_TP3)


##Model results
summary(Tol_PAM.lme_TP3)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: PAM.prop ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP3

REML criterion at convergence: -172.6

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.29399 -0.71463  0.01706  0.83761  1.77082 

Random effects:
 Groups   Name        Variance  Std.Dev.
 Genotype (Intercept) 3.177e-05 0.005637
 Residual             9.061e-04 0.030101
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                         Estimate Std. Error        df t value Pr(>|t|)    
(Intercept)              0.954325   0.009279 14.520200 102.850   <2e-16 ***
OriginTransplant         0.009025   0.012289 42.000000   0.734    0.467    
SiteSS                   0.003975   0.012289 42.000000   0.323    0.748    
OriginTransplant:SiteSS -0.019133   0.017379 42.000000  -1.101    0.277    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.662              
SiteSS      -0.662  0.500       
OrgnTrn:SSS  0.468 -0.707 -0.707
eta_squared(Tol_PAM.lme_TP3)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |       9.25e-05 | [0.00, 1.00]
Site        |       9.76e-03 | [0.00, 1.00]
Origin:Site |           0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_PAM_TP3.res<-data.frame(summary(Tol_PAM.lme_TP3)$coefficients[-1,])
Tol_PAM_TP3.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_PAM_TP3.res$EtaSq<-c(eta_squared(Tol_PAM.lme_TP3)$Eta2)
Tol_PAM_TP3.res$Response<-rep("FvFm Retention", nrow(Tol_PAM_TP3.res))
##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_PAM.pair_TP3<-emmeans(Tol_PAM.lme_TP3, pairwise~Origin | Site)
Tol_PAM.pair_TP3
$emmeans
Site = KL:
 Origin     emmean      SE   df lower.CL upper.CL
 Native      0.954 0.00928 14.5    0.934    0.974
 Transplant  0.963 0.00928 14.5    0.944    0.983

Site = SS:
 Origin     emmean      SE   df lower.CL upper.CL
 Native      0.958 0.00928 14.5    0.938    0.978
 Transplant  0.948 0.00928 14.5    0.928    0.968

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant -0.00902 0.0123 42  -0.734  0.4668

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  0.01011 0.0123 42   0.823  0.4154

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_PAM.pair.es_TP3<-data.frame(eff_size(Tol_PAM.pair_TP3, sigma=sigma(Tol_PAM.lme_TP3), edf=df.residual(Tol_PAM.lme_TP3)))
Since 'object' is a list, we are using the contrasts already present.
Tol_PAM.pair.es_TP3
Tol_PAM.pair.es_TP3<-Tol_PAM.pair.es_TP3 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_PAM.pair_TP3.res<-merge(data.frame(Tol_PAM.pair_TP3$contrasts), Tol_PAM.pair.es_TP3[,-c(1)])
Tol_PAM.pair_TP3.res$Response<-rep("FvFm Retention", nrow(Tol_PAM.pair_TP3.res))

##Add Significance levels
Tol_PAM.pair_TP3.res$Sig<-ifelse(Tol_PAM.pair_TP3.res$p.value<0.001, "***",
                              ifelse(Tol_PAM.pair_TP3.res$p.value<0.01, "**",
                                     ifelse(Tol_PAM.pair_TP3.res$p.value<0.05, "*",
                                            ifelse(Tol_PAM.pair_TP3.res$p.value<0.1, "-", NA))))
Tol_PAM.pair_TP3.res
##Summary statistics by Site and Origin
TP3_TolPAM.sum<-summarySE(Therm_TP3, measurevar="PAM.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP3_TolPAM.plot<-ggplot(TP3_TolPAM.sum, aes(x=Site, y=PAM.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=PAM.prop-se, ymax=PAM.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Photochemical Efficiency Retention", colour="Origin")+
  ylim(0.7, 1); TP3_TolPAM.plot

Save Results

##Combine Results
Tol_TP3.res<-rbind(Tol_PAM_TP3.res, Tol_Sym_TP3.res, Tol_Chl_TP3.res)
Tol.pair.res_TP3<-rbind(Tol_PAM.pair_TP3.res, Tol_Sym.pair_TP3.res, Tol_Chl.pair_TP3.res)

##Add Timepoint
Tol_TP3.res$TimeP<-rep("TP3", nrow(Tol_TP3.res))
Tol.pair.res_TP3$TimeP<-rep("TP3", nrow(Tol.pair.res_TP3))

TP4

##Subset Timepoint 4
Therm_TP4<-subset(Therm_H, TimeP=="TP4")

Symbionts

#Check normality
hist(Therm_TP4$Sym.prop)

shapiro.test(Therm_TP4$Sym.prop)

    Shapiro-Wilk normality test

data:  Therm_TP4$Sym.prop
W = 0.93453, p-value = 0.01005
#Not normal

hist(log(Therm_TP4$Sym.prop+1))

shapiro.test(log(Therm_TP4$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(Therm_TP4$Sym.prop + 1)
W = 0.95458, p-value = 0.061
#Normal

##Model with log +1 transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_Sym.lme_TP4<-lmer(log(Sym.prop+1)~Origin*Site+(1|Genotype), data=Therm_TP4)

##Check residuals
Tol_Sym.lme_res_TP4 <- simulateResiduals(fittedModel = Tol_Sym.lme_TP4, plot = F)
plot(Tol_Sym.lme_res_TP4)


##Model results
summary(Tol_Sym.lme_TP4)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: log(Sym.prop + 1) ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP4

REML criterion at convergence: -44.7

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-1.5412 -0.7855 -0.1534  0.5518  2.2412 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.001295 0.03598 
 Residual             0.016289 0.12763 
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)              0.24607    0.04230  9.94436   5.818 0.000173 ***
OriginTransplant         0.04098    0.05210 42.00002   0.787 0.435975    
SiteSS                  -0.03092    0.05210 42.00002  -0.593 0.556032    
OriginTransplant:SiteSS -0.03256    0.07369 42.00002  -0.442 0.660816    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.616              
SiteSS      -0.616  0.500       
OrgnTrn:SSS  0.436 -0.707 -0.707
eta_squared(Tol_Sym.lme_TP4)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |           0.01 | [0.00, 1.00]
Site        |           0.04 | [0.00, 1.00]
Origin:Site |       4.63e-03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_TP4.res<-data.frame(summary(Tol_Sym.lme_TP4)$coefficients[-1,])
Tol_Sym_TP4.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_Sym_TP4.res$EtaSq<-c(eta_squared(Tol_Sym.lme_TP4)$Eta2)
Tol_Sym_TP4.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym_TP4.res))
##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Sym.pair_TP4<-emmeans(Tol_Sym.lme_TP4, pairwise~Origin | Site)
Tol_Sym.pair_TP4
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.246 0.0423 9.94    0.152    0.340
 Transplant  0.287 0.0423 9.94    0.193    0.381

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.215 0.0423 9.94    0.121    0.309
 Transplant  0.224 0.0423 9.94    0.129    0.318

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant -0.04098 0.0521 42  -0.787  0.4360

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant -0.00842 0.0521 42  -0.162  0.8724

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Sym.pair.es_TP4<-data.frame(eff_size(Tol_Sym.pair_TP4, sigma=sigma(Tol_Sym.lme_TP4), edf=df.residual(Tol_Sym.lme_TP4)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Sym.pair.es_TP4
Tol_Sym.pair.es_TP4<-Tol_Sym.pair.es_TP4 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Sym.pair_TP4.res<-merge(data.frame(Tol_Sym.pair_TP4$contrasts), Tol_Sym.pair.es_TP4[,-c(1)])
Tol_Sym.pair_TP4.res$Response<-rep("Symbiont Retention", nrow(Tol_Sym.pair_TP4.res))

##Add Significance levels
Tol_Sym.pair_TP4.res$Sig<-ifelse(Tol_Sym.pair_TP4.res$p.value<0.001, "***",
                              ifelse(Tol_Sym.pair_TP4.res$p.value<0.01, "**",
                                     ifelse(Tol_Sym.pair_TP4.res$p.value<0.05, "*",
                                            ifelse(Tol_Sym.pair_TP4.res$p.value<0.1, "-", NA))))
Tol_Sym.pair_TP4.res
##Summary statistics by Site and Origin
TP4_TolSym.sum<-summarySE(Therm_TP4, measurevar="Sym.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP4_TolSym.plot<-ggplot(TP4_TolSym.sum, aes(x=Site, y=Sym.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Symbiont Retention", colour="Origin")+
  ylim(0, 1); TP4_TolSym.plot

Chlorophyll

#Check normality
hist(Therm_TP4$Chl.prop)

shapiro.test(Therm_TP4$Chl.prop)

    Shapiro-Wilk normality test

data:  Therm_TP4$Chl.prop
W = 0.94204, p-value = 0.02131
#Not normal

hist(log(Therm_TP4$Chl.prop+1))

shapiro.test(log(Therm_TP4$Chl.prop+1))

    Shapiro-Wilk normality test

data:  log(Therm_TP4$Chl.prop + 1)
W = 0.9512, p-value = 0.04824
##Nearly normal

##Model with log +1 transformation
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_Chl.lme_TP4<-lmer(log(Chl.prop+1)~Origin*Site+(1|Genotype), data=Therm_TP4)
boundary (singular) fit: see help('isSingular')
##Check residuals
Tol_Chl.lme_res_TP4 <- simulateResiduals(fittedModel = Tol_Chl.lme_TP4, plot = F)
plot(Tol_Chl.lme_res_TP4)


##Model results
summary(Tol_Chl.lme_TP4)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: log(Chl.prop + 1) ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP4

REML criterion at convergence: -139.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-1.6397 -0.7647 -0.1492  0.5006  2.4251 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.000000 0.00000 
 Residual             0.001803 0.04246 
Number of obs: 47, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)              0.09448    0.01226 43.00000   7.707 1.24e-09 ***
OriginTransplant        -0.01266    0.01734 43.00000  -0.730    0.469    
SiteSS                  -0.02659    0.01773 43.00000  -1.500    0.141    
OriginTransplant:SiteSS  0.02939    0.02479 43.00000   1.185    0.242    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.707              
SiteSS      -0.692  0.489       
OrgnTrn:SSS  0.494 -0.699 -0.715
optimizer (nloptwrap) convergence code: 0 (OK)
boundary (singular) fit: see help('isSingular')
eta_squared(Tol_Chl.lme_TP4)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |       6.26e-04 | [0.00, 1.00]
Site        |           0.02 | [0.00, 1.00]
Origin:Site |           0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_TP4.res<-data.frame(summary(Tol_Chl.lme_TP4)$coefficients[-1,])
Tol_Chl_TP4.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_Chl_TP4.res$EtaSq<-c(eta_squared(Tol_Chl.lme_TP4)$Eta2)
Tol_Chl_TP4.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl_TP4.res))
##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_Chl.pair_TP4<-emmeans(Tol_Chl.lme_TP4, pairwise~Origin | Site)
Tol_Chl.pair_TP4
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.0945 0.0123 21.6   0.0690   0.1199
 Transplant 0.0818 0.0123 21.6   0.0564   0.1073

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native     0.0679 0.0129 23.5   0.0413   0.0944
 Transplant 0.0846 0.0123 21.6   0.0592   0.1101

Degrees-of-freedom method: kenward-roger 
Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE   df t.ratio p.value
 Native - Transplant   0.0127 0.0173 41.0   0.730  0.4693

Site = SS:
 contrast            estimate     SE   df t.ratio p.value
 Native - Transplant  -0.0167 0.0178 41.2  -0.942  0.3517

Note: contrasts are still on the log(mu + 1) scale 
Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_Chl.pair.es_TP4<-data.frame(eff_size(Tol_Chl.pair_TP4, sigma=sigma(Tol_Chl.lme_TP4), edf=df.residual(Tol_Chl.lme_TP4)))
Since 'object' is a list, we are using the contrasts already present.
Tol_Chl.pair.es_TP4
Tol_Chl.pair.es_TP4<-Tol_Chl.pair.es_TP4 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_Chl.pair_TP4.res<-merge(data.frame(Tol_Chl.pair_TP4$contrasts), Tol_Chl.pair.es_TP4[,-c(1)])
Tol_Chl.pair_TP4.res$Response<-rep("Chlorophyll Retention", nrow(Tol_Chl.pair_TP4.res))

##Add Significance levels
Tol_Chl.pair_TP4.res$Sig<-ifelse(Tol_Chl.pair_TP4.res$p.value<0.001, "***",
                              ifelse(Tol_Chl.pair_TP4.res$p.value<0.01, "**",
                                     ifelse(Tol_Chl.pair_TP4.res$p.value<0.05, "*",
                                            ifelse(Tol_Chl.pair_TP4.res$p.value<0.1, "-", NA))))
Tol_Chl.pair_TP4.res
##Summary statistics by Site and Origin
TP4_TolChl.sum<-summarySE(Therm_TP4, measurevar="Chl.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP4_TolChl.plot<-ggplot(TP4_TolChl.sum, aes(x=Site, y=Chl.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Chlorophyll Retention", colour="Origin")+
  ylim(0, 0.35); TP4_TolChl.plot

FvFm

#Check normality
hist(Therm_TP4$PAM.prop)

shapiro.test(Therm_TP4$PAM.prop)

    Shapiro-Wilk normality test

data:  Therm_TP4$PAM.prop
W = 0.86379, p-value = 5.159e-05
#Not normal

hist(Therm_TP4$PAM.prop^2)

shapiro.test(Therm_TP4$PAM.prop^2)

    Shapiro-Wilk normality test

data:  Therm_TP4$PAM.prop^2
W = 0.90996, p-value = 0.00134
##Still not normal

##Model
#Function of Site and Origin, with Genotype as a Random effect
#Interaction between Site and Origin
Tol_PAM.lme_TP4<-lmer(PAM.prop^2~Origin*Site+(1|Genotype), data=Therm_TP4)

##Check residuals
Tol_PAM.lme_res_TP4 <- simulateResiduals(fittedModel = Tol_PAM.lme_TP4, plot = F)
plot(Tol_PAM.lme_res_TP4)


##Model results
summary(Tol_PAM.lme_TP4)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: PAM.prop^2 ~ Origin * Site + (1 | Genotype)
   Data: Therm_TP4

REML criterion at convergence: -31

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-1.81938 -0.46352 -0.06318  0.64045  2.58461 

Random effects:
 Groups   Name        Variance Std.Dev.
 Genotype (Intercept) 0.01982  0.1408  
 Residual             0.02031  0.1425  
Number of obs: 48, groups:  Genotype, 3

Fixed effects:
                        Estimate Std. Error       df t value Pr(>|t|)   
(Intercept)              0.58067    0.09109  2.78330   6.374  0.00976 **
OriginTransplant         0.03985    0.05818 42.00000   0.685  0.49718   
SiteSS                   0.03545    0.05818 42.00000   0.609  0.54566   
OriginTransplant:SiteSS -0.07357    0.08228 42.00000  -0.894  0.37633   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) OrgnTr SiteSS
OrgnTrnspln -0.319              
SiteSS      -0.319  0.500       
OrgnTrn:SSS  0.226 -0.707 -0.707
eta_squared(Tol_PAM.lme_TP4)
# Effect Size for ANOVA (Type III)

Parameter   | Eta2 (partial) |       95% CI
-------------------------------------------
Origin      |       1.32e-04 | [0.00, 1.00]
Site        |       2.53e-05 | [0.00, 1.00]
Origin:Site |           0.02 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_PAM_TP4.res<-data.frame(summary(Tol_PAM.lme_TP4)$coefficients[-1,])
Tol_PAM_TP4.res$Predictor<-c("Origin", "Site", "Origin x Site")
Tol_PAM_TP4.res$EtaSq<-c(eta_squared(Tol_PAM.lme_TP4)$Eta2)
Tol_PAM_TP4.res$Response<-rep("FvFm Retention", nrow(Tol_PAM_TP4.res))
##Pairwise Comparisons of Interest
#Native vs Transplant within a Site
Tol_PAM.pair_TP4<-emmeans(Tol_PAM.lme_TP4, pairwise~Origin | Site)
Tol_PAM.pair_TP4
$emmeans
Site = KL:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.581 0.0911 2.78    0.278    0.884
 Transplant  0.621 0.0911 2.78    0.317    0.924

Site = SS:
 Origin     emmean     SE   df lower.CL upper.CL
 Native      0.616 0.0911 2.78    0.313    0.919
 Transplant  0.582 0.0911 2.78    0.279    0.885

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant  -0.0398 0.0582 42  -0.685  0.4972

Site = SS:
 contrast            estimate     SE df t.ratio p.value
 Native - Transplant   0.0337 0.0582 42   0.580  0.5652

Degrees-of-freedom method: kenward-roger 
#Calculate standardized effect sizes for pairwise comparisons
Tol_PAM.pair.es_TP4<-data.frame(eff_size(Tol_PAM.pair_TP4, sigma=sigma(Tol_PAM.lme_TP4), edf=df.residual(Tol_PAM.lme_TP4)))
Since 'object' is a list, we are using the contrasts already present.
Tol_PAM.pair.es_TP4
Tol_PAM.pair.es_TP4<-Tol_PAM.pair.es_TP4 %>% dplyr::rename(contrast.se = contrast, SE.es = SE, df.es = df)

##Save Results
Tol_PAM.pair_TP4.res<-merge(data.frame(Tol_PAM.pair_TP4$contrasts), Tol_PAM.pair.es_TP4[,-c(1)])
Tol_PAM.pair_TP4.res$Response<-rep("FvFm Retention", nrow(Tol_PAM.pair_TP4.res))

##Add Significance levels
Tol_PAM.pair_TP4.res$Sig<-ifelse(Tol_PAM.pair_TP4.res$p.value<0.001, "***",
                              ifelse(Tol_PAM.pair_TP4.res$p.value<0.01, "**",
                                     ifelse(Tol_PAM.pair_TP4.res$p.value<0.05, "*",
                                            ifelse(Tol_PAM.pair_TP4.res$p.value<0.1, "-", NA))))
Tol_PAM.pair_TP4.res
##Summary statistics by Site and Origin
TP4_TolPAM.sum<-summarySE(Therm_TP4, measurevar="PAM.prop", groupvars=c("Site", "Origin", "Site.Orig"), na.rm=TRUE)

##Plot Average Retention across Treatments
TP4_TolPAM.plot<-ggplot(TP4_TolPAM.sum, aes(x=Site, y=PAM.prop, colour=Site.Orig)) + 
  scale_colour_manual(values=Orig.colors.o)+
  geom_errorbar(aes(ymin=PAM.prop-se, ymax=PAM.prop+se), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(size=point.sz, position=position_dodge(width=0.5))+
  theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x="Site and Origin", y="Photochemical Efficiency Retention", colour="Origin")+
  ylim(0.6, 1); TP4_TolPAM.plot

Save Results

##Combine Results
Tol_TP4.res<-rbind(Tol_PAM_TP4.res, Tol_Sym_TP4.res, Tol_Chl_TP4.res)
Tol.pair.res_TP4<-rbind(Tol_PAM.pair_TP4.res, Tol_Sym.pair_TP4.res, Tol_Chl.pair_TP4.res)

##Add Timepoint
Tol_TP4.res$TimeP<-rep("TP4", nrow(Tol_TP4.res))
Tol.pair.res_TP4$TimeP<-rep("TP4", nrow(Tol.pair.res_TP4))

Percent Difference in Fv/Fm

Focus on Fv/Fm at KL TP 1 and 2 where difference were significant

##Summary statistics by Genotype, Origin, Site, and Timepoint
Tol.PAM.sum<-summarySE(Therm_H, measurevar="PAM.prop", groupvars=c("Genotype", "Origin", "Site", "TimeP"), na.rm=TRUE)

##Remove Initial Timepoint
Tol.PAM.sum<-Tol.PAM.sum[-c(which(Tol.PAM.sum$TimeP=="IN")),]

##Calculate Percent Difference between Native and Transplant by Genotype
Tol.PAM.dif<-Tol.PAM.sum[which(Tol.PAM.sum$Origin=="Native"), c(1,3,4,6)]
Tol.PAM.dif<-Tol.PAM.dif %>% dplyr::rename(PAM_N = PAM.prop)
Tol.PAM.dif$PAM_T<-Tol.PAM.sum$PAM.prop[which(Tol.PAM.sum$Origin=="Transplant")]

##KL
Tol.PAM.dif_KL<-subset(Tol.PAM.dif, Site=="KL")
Tol.PAM.dif_KL$Perc.Inc<-((Tol.PAM.dif_KL$PAM_T-Tol.PAM.dif_KL$PAM_N)/Tol.PAM.dif_KL$PAM_N)*100
Tol.PAM.dif_KL

##Mean and Standard Error by Timepoint
Tol.PAM.dif_KL.sum<-summarySE(Tol.PAM.dif_KL, measurevar="Perc.Inc", groupvars=c("TimeP"), na.rm=TRUE)
Tol.PAM.dif_KL.sum

Performance Effect Sizes

Current vs Original Site

##Combine Results
Growth.TP.res<-rbind(TLE_TP1.2.res, TLE_TP3.4.res)
Growth.TP.res<-Growth.TP.res %>% dplyr::rename(TimeP = Timepoint)
Tol_TP.res<-rbind(Tol_TP1.res, Tol_TP2.res, Tol_TP3.res, Tol_TP4.res)
Perf.res<-rbind(Growth.TP.res, Tol_TP.res)
Perf.res<-Perf.res %>% dplyr::rename(p = Pr...t..)

##Responses for Figure
Perf.res.plot<-Perf.res[-c(which(Perf.res$Response=="Chlorophyll Retention")),]

##Add Significance levels
Perf.res.plot$Sig<-ifelse(Perf.res.plot$p<0.001, "***", ifelse(Perf.res.plot$p<0.01, "**", 
            ifelse(Perf.res.plot$p<0.05, "*", ifelse(Perf.res.plot$p<0.1, "-", NA))))

##Set Order
Perf.res.plot$Response<-factor(Perf.res.plot$Response, levels=c("Growth", "FvFm Retention", "Symbiont Retention"), ordered=TRUE)

##Match Growth Timepoints
Perf.res.plot$TimeP[which(Perf.res.plot$TimeP=="TP1_2")]<-"TP2"
Perf.res.plot$TimeP[which(Perf.res.plot$TimeP=="TP3_4")]<-"TP4"

Plot Effect Size of Origin and Site

Perf.Site.Orig.ES.plot<-ggplot(Perf.res.plot, aes(fill=Predictor, y=EtaSq, x=TimeP)) + 
    geom_bar(position="stack", stat="identity")+
  facet_wrap(vars(Response))+
  theme_bw()+
  scale_fill_manual(values=c("indianred2", "mediumpurple3", "steelblue2"))+
  theme(strip.text=element_text(size=axis.title.sz),
        strip.background = element_rect(fill="white"),
        axis.title.x = element_text(size = axis.title.sz), 
        axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"),
        legend.text=element_text(size=leg.txt.sz), 
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"), 
        legend.position=c(.08, .8), 
        panel.grid.major.x=element_blank())+
   labs(x="Time Point", y=expression(paste("Predictor Effect Size (p", eta^2, ")")), colour="Predictor")+
   geom_text(aes(label=Sig), position=position_stack(vjust=0.5), size=sig.sz); Perf.Site.Orig.ES.plot

Native vs Transplant

##Combine Pairwise Results
Growth.pair.res<-rbind(TLE.pair_TP1.2.res, TLE.pair_TP3.4.res)
Tol.pair.res<-rbind(Tol.pair.res_TP1, Tol.pair.res_TP2, Tol.pair.res_TP3, Tol.pair.res_TP4)
Perf.pair.res<-rbind(Growth.pair.res[,c(1:13, 15, 14)], Tol.pair.res)

##Responses for Figure
Perf.pair.res.plot<-Perf.pair.res[-c(which(Perf.pair.res$Response=="Chlorophyll Retention")),]

##Add Significance
Perf.pair.res.plot$Significant<-ifelse(Perf.pair.res.plot$p.value<0.05, "sig", "non")

##Set Order
Perf.pair.res.plot$Response<-factor(Perf.pair.res.plot$Response, levels=c("Growth", "FvFm Retention", "Symbiont Retention"), ordered=TRUE)

##Match Growth Timepoints
Perf.pair.res.plot$TimeP[which(Perf.pair.res.plot$TimeP=="TP1_2")]<-"TP2"
Perf.pair.res.plot$TimeP[which(Perf.pair.res.plot$TimeP=="TP3_4")]<-"TP4"

##Set Factors
Perf.pair.res.plot$Site<-factor(Perf.pair.res.plot$Site, levels=c("KL", "SS"))

Plot Effect Size of Origin

##Plot Effect Size across Timepoints
Perf.Orig.ES.plot<-ggplot(Perf.pair.res.plot, aes(x=TimeP, y=effect.size)) + 
  geom_rect(fill="grey90", alpha=0.4, xmin=-Inf, xmax=Inf, ymin=-.4, ymax=0.4)+
  geom_rect(fill="grey80", alpha=0.4, xmin=-Inf, xmax=Inf, ymin=-.25, ymax=0.25)+
  geom_rect(fill="grey70", alpha=0.4, xmin=-Inf, xmax=Inf, ymin=-.1, ymax=0.1)+
  geom_hline(yintercept=0, linetype="dashed", color="grey50", linewidth=0.5)+
  geom_errorbar(aes(ymin=effect.size-SE.es, ymax=effect.size+SE.es, colour=Site), width=cap.sz, linewidth=bar.sz, position=position_dodge(width=0.5)) +
  geom_point(aes(shape=Significant, colour=Site), size=point.sz, position=position_dodge(width=0.5))+
  facet_wrap(vars(Response))+
  scale_colour_manual(values=Site.colors.o)+
  scale_shape_manual(values=c(1, 16))+
  theme_bw()+
  theme(axis.title.x = element_text(size = axis.title.sz), 
        axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), 
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"), 
        legend.position=c(.1, .1),
        legend.direction = "horizontal",
        strip.text=element_text(size=axis.title.sz),
        strip.background = element_rect(fill="white"), 
        panel.grid.major.y=element_blank())+
  labs(x="Time Point", y="Origin Effect Size (Cohen's d)", colour="Site")+
  guides(shape="none"); Perf.Orig.ES.plot

Need to fix dodge for points and error bars

Trade Offs

Initial T1 and T2

Average Performance

Calculating the average of Growth (TP1 to TP2) and Thermal Tolerance (Retention of Symbionts, Chlorophyll, and Photochemical Efficiency at TP1) for each Set (Site, Genotype, Origin).

Growth

##Average
names(Growth_TP1.2)
 [1] "Site"       "ID"         "Orig"       "Origin"     "Genotype"   "TL.TP1_cm"  "TL.TP2_cm" 
 [8] "TL.TP3_cm"  "TL.TP4_cm"  "Set"        "Site.Orig"  "TP1"        "TP2"        "TP1.2_days"
[15] "Ext_cm"     "TLE_cm.day"
TP1.2_Growth_Set<-aggregate(Growth_TP1.2$TLE_cm.day, list(Growth_TP1.2$Site, Growth_TP1.2$Genotype, Growth_TP1.2$Orig), mean)
names(TP1.2_Growth_Set)<-c("Site", "Genotype", "Orig", "TLE_cm.day")

##Add Standard Error
TP1.2_Growth_Set$TLE_se<-aggregate(Growth_TP1.2$TLE_cm.day, list(Growth_TP1.2$Site, Growth_TP1.2$Genotype, Growth_TP1.2$Orig), std.error)[,4]

Tolerance

##Average
names(Therm_TP1)
 [1] "TimeP"         "Site"          "Genotype"      "Origin"        "ID"           
 [6] "RandN"         "Treat"         "Treatment"     "Orig"          "Set"          
[11] "Site.Orig"     "SA_cm2"        "Chl_ug.cm2"    "Sym10.6_cm2"   "Fv_Fm"        
[16] "Chl_ug.cm2_C"  "Sym10.6_cm2_C" "Fv_Fm_C"       "Chl.prop"      "Sym.prop"     
[21] "PAM.prop"     
T1_Therm_Set<-aggregate(Therm_TP1[,c(19:21)], list(Therm_TP1$Site, Therm_TP1$Genotype, Therm_TP1$Orig), mean)
names(T1_Therm_Set)<-c("Site", "Genotype", "Orig", "Chl.prop", "Sym.prop", "PAM.prop")

##Add Standard Error
T1_Therm_Set$Chl_se<-aggregate(Therm_TP1$Chl.prop, list(Therm_TP1$Site, Therm_TP1$Genotype, Therm_TP1$Orig), std.error)[,4]

T1_Therm_Set$Sym_se<-aggregate(Therm_TP1$Sym.prop, list(Therm_TP1$Site, Therm_TP1$Genotype, Therm_TP1$Orig), std.error)[,4]

T1_Therm_Set$PAM_se<-aggregate(Therm_TP1$PAM.prop, list(Therm_TP1$Site, Therm_TP1$Genotype, Therm_TP1$Orig), std.error)[,4]

Merge Growth and Tolerance

TP1.2_Perf_Set<-merge(TP1.2_Growth_Set, T1_Therm_Set, all=TRUE)
TP1.2_Perf_Set$Set<-paste(TP1.2_Perf_Set$Site, TP1.2_Perf_Set$Genotype, TP1.2_Perf_Set$Orig, sep=".")

##Set factor variables
TP1.2_Perf_Set$Site<-factor(TP1.2_Perf_Set$Site, levels=c("KL", "SS"))
TP1.2_Perf_Set$Genotype<-factor(TP1.2_Perf_Set$Genotype, levels=c("AC8", "AC10", "AC12"))
TP1.2_Perf_Set$Orig<-factor(TP1.2_Perf_Set$Orig, levels=c("N", "T"))

##Add a Sample Set Variable
TP1.2_Perf_Set$Set<-paste(TP1.2_Perf_Set$Site, TP1.2_Perf_Set$Genotype, TP1.2_Perf_Set$Orig, sep=".")
TP1.2_Perf_Set$Set<-factor(TP1.2_Perf_Set$Set)

##Add Site.Orig variable
TP1.2_Perf_Set$Site.Orig<-paste(TP1.2_Perf_Set$Site, TP1.2_Perf_Set$Orig, sep=".")
TP1.2_Perf_Set$Site.Orig<-factor(TP1.2_Perf_Set$Site.Orig, levels=c("KL.N", "KL.T", "SS.N", "SS.T"))

Correlation between Growth and Tolerance

Symbiont Retention

cor.test(TP1.2_Perf_Set$TLE_cm.day, TP1.2_Perf_Set$Sym.prop, method="spearman")

    Spearman's rank correlation rho

data:  TP1.2_Perf_Set$TLE_cm.day and TP1.2_Perf_Set$Sym.prop
S = 462, p-value = 0.03733
alternative hypothesis: true rho is not equal to 0
sample estimates:
       rho 
-0.6153846 
TP1.2_TLE_Sym.plot<-ggplot(TP1.2_Perf_Set, aes(x=TLE_cm.day, y=Sym.prop)) + 
   geom_smooth(method="lm", color="#AA185AFF", fill="#F8D7BFFF", se=TRUE)+
   geom_point(aes(colour=Site.Orig, shape=Genotype),size=point.sz)+
    scale_colour_manual(values=Orig.colors.o)+
  scale_shape_manual(values=Geno.shapes.o)+
   theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x=expression(paste('Growth Rate (cm day'^-1*")")), 
       y="Symbiont Retention", 
       colour="Site Origin")+
   annotate("text", x = 0.07, y = -.15, label=expression(bolditalic(paste(r[S], " = -0.615, p = 0.037"))), size=sig.sz, hjust = 0); TP1.2_TLE_Sym.plot

Chlorophyll Retention

cor.test(TP1.2_Perf_Set$TLE_cm.day, TP1.2_Perf_Set$Chl.prop, method="spearman")

    Spearman's rank correlation rho

data:  TP1.2_Perf_Set$TLE_cm.day and TP1.2_Perf_Set$Chl.prop
S = 454, p-value = 0.04884
alternative hypothesis: true rho is not equal to 0
sample estimates:
       rho 
-0.5874126 
TP1.2_TLE_Chl.plot<-ggplot(TP1.2_Perf_Set, aes(x=TLE_cm.day, y=Chl.prop)) + 
   geom_smooth(method="lm", color="#AA185AFF", fill="#F8D7BFFF", se=TRUE)+
   geom_point(aes(colour=Site.Orig, shape=Genotype),size=point.sz)+
    scale_colour_manual(values=Orig.colors.o)+
  scale_shape_manual(values=Geno.shapes.o)+
   theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x=expression(paste('Growth Rate (cm day'^-1*")")), 
       y="Chlorophyll Retention", 
       colour="Site Origin")+
   annotate("text", x = 0.07, y = -.05, label=expression(bolditalic(paste(r[S], " = -0.587, p = 0.049"))), size=sig.sz, hjust = 0); TP1.2_TLE_Chl.plot

FvFm Retention

cor.test(TP1.2_Perf_Set$TLE_cm.day, TP1.2_Perf_Set$PAM.prop, method="spearman")

    Spearman's rank correlation rho

data:  TP1.2_Perf_Set$TLE_cm.day and TP1.2_Perf_Set$PAM.prop
S = 480, p-value = 0.01883
alternative hypothesis: true rho is not equal to 0
sample estimates:
       rho 
-0.6783217 
TP1.2_TLE_PAM.plot<-ggplot(TP1.2_Perf_Set, aes(x=TLE_cm.day, y=PAM.prop)) + 
   geom_smooth(method="lm", color="#AA185AFF", fill="#F8D7BFFF", se=TRUE)+
   geom_point(aes(colour=Site.Orig, shape=Genotype),size=point.sz)+
    scale_colour_manual(values=Orig.colors.o)+
  scale_shape_manual(values=Geno.shapes.o)+
   theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x=expression(paste('Growth Rate (cm day'^-1*")")), 
       y="Photo. Effic. Retention", 
       colour="Site Origin")+
   annotate("text", x = 0.07, y = 0.7, label=expression(bolditalic(paste(r[S], " = -0.678, p = 0.019"))), size=sig.sz, hjust = 0); TP1.2_TLE_PAM.plot

Final T3 and T4

Average Performance

Calculating the average of Growth (TP3 to TP4) and Thermal Tolerance (Retention of Symbionts, Chlorophyll, and Photochemical Efficiency at TP3) for each Set (Site, Genotype, Origin).

Growth

##Average
names(Growth_TP3.4)
 [1] "Site"       "ID"         "Orig"       "Origin"     "Genotype"   "TL.TP1_cm"  "TL.TP2_cm" 
 [8] "TL.TP3_cm"  "TL.TP4_cm"  "Set"        "Site.Orig"  "TP3"        "TP4"        "TP3.4_days"
[15] "Ext_cm"     "TLE_cm.day"
TP3.4_Growth_Set<-aggregate(Growth_TP3.4$TLE_cm.day, list(Growth_TP3.4$Site, Growth_TP3.4$Genotype, Growth_TP3.4$Orig), mean)
names(TP3.4_Growth_Set)<-c("Site", "Genotype", "Orig", "TLE_cm.day")

##Add Standard Error
TP3.4_Growth_Set$TLE_se<-aggregate(Growth_TP3.4$TLE_cm.day, list(Growth_TP3.4$Site, Growth_TP3.4$Genotype, Growth_TP3.4$Orig), std.error)[,4]

Tolerance

##Average
names(Therm_TP4)
 [1] "TimeP"         "Site"          "Genotype"      "Origin"        "ID"           
 [6] "RandN"         "Treat"         "Treatment"     "Orig"          "Set"          
[11] "Site.Orig"     "SA_cm2"        "Chl_ug.cm2"    "Sym10.6_cm2"   "Fv_Fm"        
[16] "Chl_ug.cm2_C"  "Sym10.6_cm2_C" "Fv_Fm_C"       "Chl.prop"      "Sym.prop"     
[21] "PAM.prop"     
T4_Therm_Set<-aggregate(Therm_TP4[,c(19:21)], list(Therm_TP4$Site, Therm_TP4$Genotype, Therm_TP4$Orig), mean)
names(T4_Therm_Set)<-c("Site", "Genotype", "Orig", "Chl.prop", "Sym.prop", "PAM.prop")

##Add Standard Error
T4_Therm_Set$Chl_se<-aggregate(Therm_TP4$Chl.prop, list(Therm_TP4$Site, Therm_TP4$Genotype, Therm_TP4$Orig), std.error)[,4]

T4_Therm_Set$Sym_se<-aggregate(Therm_TP4$Sym.prop, list(Therm_TP4$Site, Therm_TP4$Genotype, Therm_TP4$Orig), std.error)[,4]

T4_Therm_Set$PAM_se<-aggregate(Therm_TP4$PAM.prop, list(Therm_TP4$Site, Therm_TP4$Genotype, Therm_TP4$Orig), std.error)[,4]

Merge Growth and Tolerance

TP3.4_Perf_Set<-merge(TP3.4_Growth_Set, T4_Therm_Set, all=TRUE)
TP3.4_Perf_Set$Set<-paste(TP3.4_Perf_Set$Site, TP3.4_Perf_Set$Genotype, TP3.4_Perf_Set$Orig, sep=".")

##Set factor variables
TP3.4_Perf_Set$Site<-factor(TP3.4_Perf_Set$Site, levels=c("KL", "SS"))
TP3.4_Perf_Set$Genotype<-factor(TP3.4_Perf_Set$Genotype, levels=c("AC8", "AC10", "AC12"))
TP3.4_Perf_Set$Orig<-factor(TP3.4_Perf_Set$Orig, levels=c("N", "T"))

##Add a Sample Set Variable
TP3.4_Perf_Set$Set<-paste(TP3.4_Perf_Set$Site, TP3.4_Perf_Set$Genotype, TP3.4_Perf_Set$Orig, sep=".")
TP3.4_Perf_Set$Set<-factor(TP3.4_Perf_Set$Set)

##Add Site.Orig variable
TP3.4_Perf_Set$Site.Orig<-paste(TP3.4_Perf_Set$Site, TP3.4_Perf_Set$Orig, sep=".")
TP3.4_Perf_Set$Site.Orig<-factor(TP3.4_Perf_Set$Site.Orig, levels=c("KL.N", "KL.T", "SS.N", "SS.T"))

Correlation between Growth and Tolerance

Symbiont Retention

cor.test(TP3.4_Perf_Set$TLE_cm.day, TP3.4_Perf_Set$Sym.prop, method="spearman")

    Spearman's rank correlation rho

data:  TP3.4_Perf_Set$TLE_cm.day and TP3.4_Perf_Set$Sym.prop
S = 444, p-value = 0.06663
alternative hypothesis: true rho is not equal to 0
sample estimates:
       rho 
-0.5524476 
TP3.4_TLE_Sym.plot<-ggplot(TP3.4_Perf_Set, aes(x=TLE_cm.day, y=Sym.prop)) + 
   geom_smooth(method="lm", color="#AA185AFF", fill="#F8D7BFFF", se=TRUE)+
   geom_point(aes(colour=Site.Orig, shape=Genotype),size=point.sz)+
    scale_colour_manual(values=Orig.colors.o)+
  scale_shape_manual(values=Geno.shapes.o)+
   theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x=expression(paste('Growth Rate (cm day'^-1*")")), 
       y="Symbiont Retention", 
       colour="Site Origin")+
   annotate("text", x = 0.07, y = 0.1, label=expression(italic(paste(r[S], " = -0.552, p = 0.067"))), size=sig.sz, hjust = 0); TP3.4_TLE_Sym.plot

Chlorophyll Retention

cor.test(TP3.4_Perf_Set$TLE_cm.day, TP3.4_Perf_Set$Chl.prop, method="spearman")

    Spearman's rank correlation rho

data:  TP3.4_Perf_Set$TLE_cm.day and TP3.4_Perf_Set$Chl.prop
S = 148, p-value = 0.327
alternative hypothesis: true rho is not equal to 0
sample estimates:
      rho 
0.3272727 
TP3.4_TLE_Chl.plot<-ggplot(TP3.4_Perf_Set, aes(x=TLE_cm.day, y=Chl.prop)) + 
   geom_smooth(method="lm", color="#AA185AFF", fill="#F8D7BFFF", se=TRUE)+
   geom_point(aes(colour=Site.Orig, shape=Genotype),size=point.sz)+
    scale_colour_manual(values=Orig.colors.o)+
  scale_shape_manual(values=Geno.shapes.o)+
   theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x=expression(paste('Growth Rate (cm day'^-1*")")), 
       y="Chlorophyll Retention", 
       colour="Site Origin")+
   annotate("text", x = 0.07, y = 0.065, label=expression(italic(paste(r[S], " = 0.327, p = 0.327"))), size=sig.sz, hjust = 0); TP3.4_TLE_Chl.plot

FvFm Retention

cor.test(TP3.4_Perf_Set$TLE_cm.day, TP3.4_Perf_Set$PAM.prop, method="spearman")

    Spearman's rank correlation rho

data:  TP3.4_Perf_Set$TLE_cm.day and TP3.4_Perf_Set$PAM.prop
S = 500, p-value = 0.007353
alternative hypothesis: true rho is not equal to 0
sample estimates:
       rho 
-0.7482517 
TP3.4_TLE_PAM.plot<-ggplot(TP3.4_Perf_Set, aes(x=TLE_cm.day, y=PAM.prop)) + 
   geom_smooth(method="lm", color="#AA185AFF", fill="#F8D7BFFF", se=TRUE)+
   geom_point(aes(colour=Site.Orig, shape=Genotype),size=point.sz)+
    scale_colour_manual(values=Orig.colors.o)+
  scale_shape_manual(values=Geno.shapes.o)+
   theme_classic()+
  theme(axis.title.x = element_text(size = axis.title.sz), axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"), axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz), legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"))+
  labs(x=expression(paste('Growth Rate (cm day'^-1*")")), 
       y="Photo. Effic. Retention", 
       colour="Site Origin")+
   annotate("text", x = 0.07, y = 0.5, label=expression(bolditalic(paste(r[S], " = -0.748, p = 0.007"))), size=sig.sz, hjust = 0); TP3.4_TLE_PAM.plot

Figures

Figure 4 Performance Effect Sizes

Adjust for Panel

Perf.Site.Orig.ES.plot<-Perf.Site.Orig.ES.plot+ labs(x="")

Figure 4

##Create Panel
Perf.ES_fig<-plot_grid(Perf.Site.Orig.ES.plot, Perf.Orig.ES.plot, 
                    rel_widths=1, rel_heights = 1,
                    nrow=2, ncol=1, byrow=T, labels = c("A", "B"), 
                    label_size=panel.lab.sz)
Warning: Removed 18 rows containing missing values (`geom_text()`).
##Save Figure
ggsave(filename="Figures/03_Performance/Fig4_PerformanceEffectSizes.png", plot=Perf.ES_fig, dpi=300, width=12, height=9, units="in")

Figure 5 Growth vs Tolerance

Adjust Figures for Panel

##Timepoint 1 to 2
TP1.2_TLE_PAM.plot<-TP1.2_TLE_PAM.plot + ggtitle("Photo. Effic.")+ labs(x=NULL, y = "Tolerance (Retention)")+
  theme(plot.title = element_text(colour="black", size=panel.lab.sz, hjust=0.5), legend.position="none")

TP1.2_TLE_Sym.plot<- TP1.2_TLE_Sym.plot + ggtitle("Symbionts")+ labs(x=NULL, y = NULL)+
  theme(plot.title = element_text(colour="black", size=panel.lab.sz, hjust=0.5)) + ylim(-.15, .8)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
##Timepoint 3 to 4
TP3.4_TLE_PAM.plot<-TP3.4_TLE_PAM.plot + labs(y = "Tolerance (Retention)") +
  theme(legend.position="none")

TP3.4_TLE_Sym.plot<-TP3.4_TLE_Sym.plot + labs(y = NULL)

Figure 5

##Create Panel
TradeOff_fig<-plot_grid(TP1.2_TLE_PAM.plot, TP1.2_TLE_Sym.plot,
                      TP3.4_TLE_PAM.plot, TP3.4_TLE_Sym.plot,
                    rel_widths=c(.75, 1), rel_heights = c(1, .98),
                    nrow=2, ncol=2, byrow=T, 
                    labels = c("A", "B", "C", "D"), 
                    label_size=panel.lab.sz)
`geom_smooth()` using formula = 'y ~ x'Warning: is.na() applied to non-(list or vector) of type 'expression'`geom_smooth()` using formula = 'y ~ x'Warning: Removed 1 rows containing non-finite values (`stat_smooth()`).Warning: Removed 1 rows containing missing values (`geom_point()`).Warning: is.na() applied to non-(list or vector) of type 'expression'`geom_smooth()` using formula = 'y ~ x'Warning: is.na() applied to non-(list or vector) of type 'expression'`geom_smooth()` using formula = 'y ~ x'Warning: is.na() applied to non-(list or vector) of type 'expression'
##Save Figure
ggsave(filename="Figures/03_Performance/Fig5_TradeOff.png", plot=TradeOff_fig, dpi=300, width=8, height=8, units="in")

Figure S5 Growth

Adjust Figures for Panel

##TP 1 to TP 2
TP1.2_Growth.plot<-TP1.2_Growth.plot+ ggtitle("TP1 to TP2")+
  theme(plot.title = element_text(colour="black", 
                                  size=panel.lab.sz, hjust=0.5), 
        legend.position=c(0.25, 0.85), legend.direction="horizontal")+
  labs(colour=NULL)+
  guides(color=guide_legend(nrow=2, byrow=FALSE)) 


##TP 3 to TP 4
TP3.4_Growth.plot<-TP3.4_Growth.plot+ ggtitle("TP3 to TP4")+
  theme(plot.title = element_text(colour="black", 
                                  size=panel.lab.sz, hjust=0.5), 
        legend.position="none")

Figure S5

##Create Panel
Growth_fig<-plot_grid(TP1.2_Growth.plot, TP3.4_Growth.plot, 
                    rel_widths=1, rel_heights = 1,
                    nrow=1, ncol=2, byrow=T, labels = c("A", "B"), 
                    label_size=panel.lab.sz)

##Save Figure
ggsave(filename="Figures/03_Performance/FigS5_Growth.png", plot=Growth_fig, dpi=300, width=10, height=4.5, units="in")

Figure S6 Initial Heat Assay

Adjust Figures for Panel

##FvFm
IN_PAM.plot<-IN_PAM.plot + labs(x="", y="Fv/Fm") + theme(legend.position="none") + ylim(0.5, 0.655)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
IN_TolPAM.plot<-IN_TolPAM.plot + labs(x="", y="Retention") + 
  theme(legend.position="none") + ylim(0.75, 1)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
##Symbionts
IN_Sym.plot<-IN_Sym.plot + labs(x="", y="Symbionts") + theme(legend.position="none") + ylim(0,1)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
IN_TolSym.plot<-IN_TolSym.plot + labs(x="", y="Retention") + 
  theme(legend.position="none") + ylim(.25, .75)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
##Chlorophyll
IN_Chl.plot<-IN_Chl.plot + labs(x="Site and Treatment", y="Chlorophyll") + 
  theme(legend.position="none") + ylim(0,1.25)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
IN_TolChl.plot<-IN_TolChl.plot + labs(x="Site", y="Retention") + 
  theme(legend.position="none") + ylim(0, 0.25)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.

Figure S6

##Create Panel
IN_HeatAssay_fig<-plot_grid(IN_PAM.plot, IN_TolPAM.plot, 
                      IN_Sym.plot, IN_TolSym.plot,
                      IN_Chl.plot, IN_TolChl.plot,
                    rel_widths=c(1, 0.75), 
                    rel_heights = c(1, 1, 1),
                    nrow=3, ncol=2, byrow=T, 
                    labels = c("A", "B", "C", "D", "E", "F"), 
                    label_size=panel.lab.sz)

##Save Figure
ggsave(filename="Figures/03_Performance/FigS6_InitialHeatAssay.png", plot=IN_HeatAssay_fig, dpi=300, width=8, height=11, units="in")

Figure S7 Thermal Tolerance

Adjust Figures for Panel

##FvFm Retention
TP1_TolPAM.plot<-TP1_TolPAM.plot + ggtitle("TP1")+ 
  labs(x=NULL, y="Photo. Effic. Retention", colour=NULL)+
  theme(plot.title = element_text(colour="black", size=panel.lab.sz, face="bold", hjust=0.5), 
        legend.position=c(0.5, 0.15), legend.direction="horizontal")+
  guides(color=guide_legend(nrow=2, byrow=FALSE))

TP2_TolPAM.plot<-TP2_TolPAM.plot+ ggtitle("TP2")+ labs(x=NULL, y=NULL) +
  theme(plot.title = element_text(colour="black", size=panel.lab.sz, face="bold", hjust=0.5), 
        legend.position="none")

TP3_TolPAM.plot<-TP3_TolPAM.plot+ ggtitle("TP3")+ labs(x=NULL, y=NULL) +
  theme(plot.title = element_text(colour="black", size=panel.lab.sz, face="bold", hjust=0.5), 
        legend.position="none")

TP4_TolPAM.plot<-TP4_TolPAM.plot+ ggtitle("TP4")+ labs(x=NULL, y=NULL) +
  theme(plot.title = element_text(colour="black", size=panel.lab.sz, face="bold", hjust=0.5), 
        legend.position="none")


##Symbiont Retention
TP1_TolSym.plot<- TP1_TolSym.plot + labs(x=NULL) + theme(legend.position="none")

TP2_TolSym.plot<- TP2_TolSym.plot + labs(x=NULL, y=NULL) + theme(legend.position="none")

TP3_TolSym.plot<- TP3_TolSym.plot + labs(x=NULL, y=NULL) + theme(legend.position="none")

TP4_TolSym.plot<- TP4_TolSym.plot + labs(x=NULL, y=NULL) + theme(legend.position="none")


##Chlorophyll Retention
TP1_TolChl.plot<-TP1_TolChl.plot + theme(legend.position="none")

TP2_TolChl.plot<-TP2_TolChl.plot + labs(y=NULL) + theme(legend.position="none")

TP3_TolChl.plot<-TP3_TolChl.plot + labs(y=NULL) + theme(legend.position="none")

TP4_TolChl.plot<-TP4_TolChl.plot + labs(y=NULL) + theme(legend.position="none")

Figure S7

##Create Panel
Tolerance_fig<-plot_grid(TP1_TolPAM.plot, TP2_TolPAM.plot, 
                      TP3_TolPAM.plot, TP4_TolPAM.plot, 
                      TP1_TolSym.plot, TP2_TolSym.plot, 
                      TP3_TolSym.plot, TP4_TolSym.plot, 
                      TP1_TolChl.plot, TP2_TolChl.plot, 
                      TP3_TolChl.plot, TP4_TolChl.plot, 
                    rel_widths=1, rel_heights = 1,
                    nrow=3, ncol=4, byrow=T, labels = NULL)

##Save Figure
ggsave(filename="Figures/03_Performance/FigS7_Tolerance.png", plot=Tolerance_fig, dpi=300, width=14, height=12, units="in")

Tables

Table S6 Performance LM

##Combine Results Tables
TableS6_Perf.LM<-Perf.res
  
##Organize
names(TableS6_Perf.LM)
[1] "Estimate"   "Std..Error" "df"         "t.value"    "p"          "Predictor"  "EtaSq"     
[8] "Response"   "TimeP"     
TableS6_Perf.LM<-TableS6_Perf.LM %>% dplyr::rename(SE = Std..Error, DF = df, t = t.value, Timepoint = TimeP)
TableS6_Perf.LM<-TableS6_Perf.LM[,c("Timepoint", "Response", "Predictor", "Estimate", "SE", "DF", "t", "p", "EtaSq")]

#Round to 3 digits
TableS6_Perf.LM$Estimate<-round(TableS6_Perf.LM$Estimate, 3)
TableS6_Perf.LM$SE<-round(TableS6_Perf.LM$SE, 3)
TableS6_Perf.LM$t<-round(TableS6_Perf.LM$t, 3)
TableS6_Perf.LM$p<-round(TableS6_Perf.LM$p, 3)
TableS6_Perf.LM$EtaSq<-round(TableS6_Perf.LM$EtaSq, 3)

#Integer
TableS6_Perf.LM$DF<-round(TableS6_Perf.LM$DF, 0)

##Write Out Table
write.csv(TableS6_Perf.LM, "Tables/TableS6_Performance_LM_Results.csv", row.names=FALSE)

Table S7 Performance Pairwise

##Save Results Table
TableS7_Perf.pair<-Perf.pair.res

##Organize
names(TableS7_Perf.pair)
 [1] "Site"        "contrast"    "estimate"    "SE"          "df"          "t.ratio"    
 [7] "p.value"     "effect.size" "SE.es"       "df.es"       "lower.CL"    "upper.CL"   
[13] "Response"    "Sig"         "TimeP"      
TableS7_Perf.pair<-TableS7_Perf.pair %>% dplyr::rename(Timepoint = TimeP, Contrast =contrast, Estimate = estimate, DF = df, t = t.ratio, p = p.value, EffectSize = effect.size, EffectSize.SE = SE.es)
TableS7_Perf.pair<-TableS7_Perf.pair[,c("Timepoint", "Response", "Site", "Contrast", "Estimate", "SE", "DF", "t", "p", "EffectSize", "EffectSize.SE")]

#Round to 3 digits
TableS7_Perf.pair$Estimate<-round(TableS7_Perf.pair$Estimate, 3)
TableS7_Perf.pair$SE<-round(TableS7_Perf.pair$SE, 3)
TableS7_Perf.pair$t<-round(TableS7_Perf.pair$t, 3)
TableS7_Perf.pair$p<-round(TableS7_Perf.pair$p, 3)
TableS7_Perf.pair$EffectSize<-round(TableS7_Perf.pair$EffectSize, 3)
TableS7_Perf.pair$EffectSize.SE<-round(TableS7_Perf.pair$EffectSize.SE, 3)

#Integer
TableS7_Perf.pair$DF<-round(TableS7_Perf.pair$DF, 0)

##Write Out Table
write.csv(TableS7_Perf.pair, "Tables/TableS7_Performance_Pairwise_Results.csv", row.names=FALSE)

Table S8 Initial Heat Assay LM

##Combine Results Tables
TableS8_IN_Tolerance<-data.frame(rbind(PAM_IN.res, Sym_IN.res, Chl_IN.res))

##Organize
names(TableS8_IN_Tolerance)
[1] "estimate"  "SE"        "df"        "t.ratio"   "p.value"   "Predictor" "Response" 
[8] "EtaSq"    
TableS8_IN_Tolerance<-TableS8_IN_Tolerance %>% dplyr::rename(Estimate = estimate, DF = df, t = t.ratio, p = p.value, EffectSize = EtaSq)
TableS8_IN_Tolerance<-TableS8_IN_Tolerance[,c("Response", "Predictor", "Estimate", "SE", "DF", "t", "p", "EffectSize")]

#Round to 3 digits
TableS8_IN_Tolerance$Estimate<-round(TableS8_IN_Tolerance$Estimate, 3)
TableS8_IN_Tolerance$SE<-round(TableS8_IN_Tolerance$SE, 3)
TableS8_IN_Tolerance$t<-round(TableS8_IN_Tolerance$t, 3)
TableS8_IN_Tolerance$p<-round(TableS8_IN_Tolerance$p, 3)
TableS8_IN_Tolerance$EffectSize<-round(TableS8_IN_Tolerance$EffectSize, 3)

#Integer
TableS8_IN_Tolerance$DF<-round(TableS8_IN_Tolerance$DF, 0)

##Write Out Table
write.csv(TableS8_IN_Tolerance, "Tables/TableS8_Initial_Tolerance_LM_Results.csv", row.names=FALSE)
LS0tDQp0aXRsZTogIkNvcmFsIFBlcmZvcm1hbmNlIEZvbGxvd2luZyBSZWNpcHJvY2FsIFRyYW5zcGxhbnQiDQphdXRob3I6ICJTZXJlbmEgSGFja2Vyb3R0IGFuZCBDYXJseSBUcmF2ZXJzIg0KZGF0ZTogIjEvMy8yMDI0Ig0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCiMgU2V0dXANCg0KYGBge3IgU2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpDQpgYGANCg0KDQojIyMgTG9hZCBQYWNrYWdlcw0KYGBge3J9DQojI0luc3RhbGwgUGFja2FnZXMgaWYgTmVlZGVkDQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQppZiAoIXJlcXVpcmUoImNvd3Bsb3QiKSkgaW5zdGFsbC5wYWNrYWdlcygiY293cGxvdCIpDQppZiAoIXJlcXVpcmUoImx1YnJpZGF0ZSIpKSBpbnN0YWxsLnBhY2thZ2VzKCJsdWJyaWRhdGUiKQ0KaWYgKCFyZXF1aXJlKCJjb3JycGxvdCIpKSBpbnN0YWxsLnBhY2thZ2VzKCJjb3JycGxvdCIpDQppZiAoIXJlcXVpcmUoImxtZTQiKSkgaW5zdGFsbC5wYWNrYWdlcygibG1lNCIpDQppZiAoIXJlcXVpcmUoInZlZ2FuIikpIGluc3RhbGwucGFja2FnZXMoInZlZ2FuIikNCmlmICghcmVxdWlyZSgiREhBUk1hIikpIGluc3RhbGwucGFja2FnZXMoIkRIQVJNYSIpDQppZiAoIXJlcXVpcmUoImVmZmVjdHNpemUiKSkgaW5zdGFsbC5wYWNrYWdlcygiZWZmZWN0c2l6ZSIpDQppZiAoIXJlcXVpcmUoImVtbWVhbnMiKSkgaW5zdGFsbC5wYWNrYWdlcygiZW1tZWFucyIpDQppZiAoIXJlcXVpcmUoImxtZXJUZXN0IikpIGluc3RhbGwucGFja2FnZXMoImxtZXJUZXN0IikNCmlmICghcmVxdWlyZSgidGlkeXIiKSkgaW5zdGFsbC5wYWNrYWdlcygidGlkeXIiKQ0KaWYgKCFyZXF1aXJlKCJkcGx5ciIpKSBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQppZiAoIXJlcXVpcmUoInBsb3RyaXgiKSkgaW5zdGFsbC5wYWNrYWdlcygicGxvdHJpeCIpDQppZiAoIXJlcXVpcmUoIlJtaXNjIikpIGluc3RhbGwucGFja2FnZXMoIlJtaXNjIikNCmlmICghcmVxdWlyZSgiZ2dwdWJyIikpIGluc3RhbGwucGFja2FnZXMoImdncHViciIpDQoNCiMjTG9hZCBQYWNrYWdlcw0KbGlicmFyeShnZ3Bsb3QyKSAjUmVxdWlyZWQgZm9yIGdncGxvdHMNCmxpYnJhcnkoY293cGxvdCkgI1JlcXVpcmVkIGZvciBwbG90dGluZyBwYW5lbCBmaWd1cmVzDQpsaWJyYXJ5KGx1YnJpZGF0ZSkgI1JlcXVpcmVkIGZvciBkYXRlIGFuZCB0aW1lIGZvcm1hdHRpbmcNCmxpYnJhcnkoY29ycnBsb3QpICNSZXF1aXJlZCBmb3IgY29ycmVsYXRpb24gcGxvdA0KbGlicmFyeShsbWU0KSAjUmVxdWlyZWQgZm9yIG1peGVkIGVmZmVjdHMgbW9kZWxpbmcNCmxpYnJhcnkodmVnYW4pICNSZXF1aXJlZCBmb3IgbXVsdGl2YXJpYXRlIGFuYWx5c2lzIFBFUk0NCmxpYnJhcnkoREhBUk1hKSAjUmVxdWlyZWQgdG8gY2hlY2sgcmVzaWR1YWxzIG9mIG1peGVkIGVmZmVjdHMgbW9kZWxzDQpsaWJyYXJ5KGVmZmVjdHNpemUpICNSZXF1aXJlZCBmb3IgZXRhX3NxdWFyZWQgZWZmZWN0IHNpemVzDQpsaWJyYXJ5KGVtbWVhbnMpICNSZXF1aXJlZCBmb3IgcGFpcndpc2UgY29tcGFyaXNvbnMgDQpsaWJyYXJ5KGxtZXJUZXN0KSAjUmVxdWlyZWQgZm9yIHAgdmFsdWVzIHdpdGggbG1lNCBtb2RlbCBzdW1tYXJpZXMNCmxpYnJhcnkodGlkeXIpICNSZXF1aXJlZCBmb3IgcGl2b3Rfd2lkZXIgZnVuY3Rpb24NCmxpYnJhcnkoZHBseXIpICNSZXF1aXJlZCBmb3IgZ3JvdXBfYnkgZnVuY3Rpb24NCmxpYnJhcnkocGxvdHJpeCkgI1JlcXVpcmVkIGZvciBTdGFuZGFyZCBlcnJvciBmdW5jdGlvbg0KbGlicmFyeShSbWlzYykgI1JlcXVpcmVkIGZvciBTdW1tYXJ5U0UgZnVuY3Rpb24NCmxpYnJhcnkoZ2dwdWJyKSAjUmVxdWlyZWQgZm9yIHN0YXQgYnJhY2tldHMNCg0KYGBgDQoNCg0KIyMjIEdyYXBoaW5nIFBhcmFtZXRlcnMNCmBgYHtyfQ0KI05vdGU6IFJ1biAiR3JhcGhpbmcgUGFyYW1ldGVycyIgc2VjdGlvbiBmcm9tIDAxX0V4cGVyaW1lbnRhbFNldHVwLlJtZCBmaWxlDQpgYGANCg0KDQojIFNhbXBsZSBEYXRhIGFuZCBNZXRhZGF0YQ0KDQojIyMgTG9hZCBhbmQgT3JnYW5pemUgRGF0YQ0KYGBge3J9DQojI0dyb3d0aA0KTGVuZ3RoPC1yZWFkLmNzdigiRGF0YS9MZW5ndGhGdWxsLmNzdiIsIGhlYWRlcj1UUlVFKQ0KRGF0ZXM8LXJlYWQuY3N2KCJEYXRhL0JvbmFpcmVEYXRlcy5jc3YiLCBoZWFkZXI9VFJVRSkNCg0KIyNTZXQgZGF0ZSB2YXJpYWJsZXMNCkRhdGVzJERhdGU8LWFzLkRhdGUoRGF0ZXMkRGF0ZSwgZm9ybWF0PSclbS8lZC8lWScpDQoNCiMjU2V0IGZhY3RvciB2YXJpYWJsZXMNCkxlbmd0aCRTaXRlPC1mYWN0b3IoTGVuZ3RoJFNpdGUsIGxldmVscz1jKCJLTCIsICJTUyIpKQ0KTGVuZ3RoJEdlbm90eXBlPC1mYWN0b3IoTGVuZ3RoJEdlbm90eXBlLCBsZXZlbHM9YygiQUM4IiwgIkFDMTAiLCAiQUMxMiIpKQ0KTGVuZ3RoJE9yaWc8LWZhY3RvcihMZW5ndGgkT3JpZywgbGV2ZWxzPWMoIk4iLCAiVCIpKQ0KTGVuZ3RoJE9yaWdpbjwtZmFjdG9yKExlbmd0aCRPcmlnaW4sIGxldmVscz1jKCJOYXRpdmUiLCAiVHJhbnNwbGFudCIpKQ0KDQojI0FkZCBhIFNhbXBsZSBTZXQgVmFyaWFibGUNCkxlbmd0aCRTZXQ8LXBhc3RlKExlbmd0aCRTaXRlLCBMZW5ndGgkR2Vub3R5cGUsIExlbmd0aCRPcmlnLCBzZXA9Ii4iKQ0KTGVuZ3RoJFNldDwtZmFjdG9yKExlbmd0aCRTZXQpDQoNCiMjQWRkIFNpdGUuT3JpZyB2YXJpYWJsZQ0KTGVuZ3RoJFNpdGUuT3JpZzwtcGFzdGUoTGVuZ3RoJFNpdGUsIExlbmd0aCRPcmlnLCBzZXA9Ii4iKQ0KTGVuZ3RoJFNpdGUuT3JpZzwtZmFjdG9yKExlbmd0aCRTaXRlLk9yaWcsIGxldmVscz1jKCJLTC5OIiwgIktMLlQiLCAiU1MuTiIsICJTUy5UIikpDQoNCg0KIyNCbGVhY2hpbmcgTWV0cmljcw0KI05vdGU6IFBoeXNpb2xvZ2ljYWwgbWV0cmljcyBjYWxjdWxhdGVkIGluIDAyX1BoeXNpb2xvZ3lNZXRyaWNzLlIgZmlsZQ0KVGhlcm1hbDwtcmVhZC5jc3YoIk91dHB1dHMvVGhlcm1EYXRhLmNzdiIsIGhlYWRlcj1UUlVFKQ0KDQojI1NldCBmYWN0b3IgdmFyaWFibGVzDQpUaGVybWFsJFRpbWVQPC1mYWN0b3IoVGhlcm1hbCRUaW1lUCwgbGV2ZWxzPWMoIklOIiwgIlRQMSIsICJUUDIiLCAiVFAzIiwgIlRQNCIpKQ0KVGhlcm1hbCRTaXRlPC1mYWN0b3IoVGhlcm1hbCRTaXRlLCBsZXZlbHM9YygiS0wiLCAiU1MiKSkNClRoZXJtYWwkR2Vub3R5cGU8LWZhY3RvcihUaGVybWFsJEdlbm90eXBlLCBsZXZlbHM9YygiQUM4IiwgIkFDMTAiLCAiQUMxMiIpKQ0KVGhlcm1hbCRPcmlnPC1mYWN0b3IoVGhlcm1hbCRPcmlnLCBsZXZlbHM9YygiTiIsICJUIikpDQpUaGVybWFsJE9yaWdpbjwtZmFjdG9yKFRoZXJtYWwkT3JpZ2luLCBsZXZlbHM9YygiTmF0aXZlIiwgIlRyYW5zcGxhbnQiKSkNCg0KYGBgDQoNCg0KIyBHcm93dGgNCg0KIyMjIEdyb3d0aCBSYXRlIFRQMSB0byBUUDINCg0KIyMjIyBDYWxjdWxhdGUgRGF5cw0KYGBge3J9DQojI1N1YnNldCBEYXRlcyBmb3IgVFAgMSBhbmQgVFAgMiBHcm93dGgNCkdyb3d0aC5EYXRlc19UUDEuMjwtc3Vic2V0KERhdGVzLCBUYXNrPT0iR3Jvd3RoIiAmIFRpbWVQPT0iVFAxIiB8DQogICAgICAgICAgICAgICAgICAgICAgIFRhc2s9PSJHcm93dGgiICYgVGltZVA9PSJUUDIiICkNCg0KIyNDb252ZXJ0IHRvIFdpZGUgZm9ybWF0DQpHcm93dGguRGF0ZXNfVFAxLjI8LUdyb3d0aC5EYXRlc19UUDEuMiAlPiUgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBUaW1lUCwgdmFsdWVzX2Zyb20gPSBEYXRlKQ0KDQojI0NhbGN1bGF0ZSBOdW1iZXIgb2YgRGF5cw0KI1RQIDEgdG8gVFAyDQpHcm93dGguRGF0ZXNfVFAxLjIkVFAxLjJfZGF5czwtdGltZV9sZW5ndGgoR3Jvd3RoLkRhdGVzX1RQMS4yJFRQMi1Hcm93dGguRGF0ZXNfVFAxLjIkVFAxLCB1bml0PSJkYXlzIikNCg0KYGBgDQoNCg0KIyMjIyBDYWxjdWxhdGUgVG90YWwgTGluZWFyIEV4dGVuc2lvbg0KYGBge3J9DQojI01lcmdlIExlbmd0aCBEYXRhIHdpdGggR3Jvd3RoIERhdGVzDQojTWVyZ2VzIGJ5IFNpdGUgY29sdW1uDQojQWRkcyBUUDEuMl9kYXlzIGNvbHVtbg0KR3Jvd3RoX1RQMS4yPC1tZXJnZShMZW5ndGgsIEdyb3d0aC5EYXRlc19UUDEuMlssYygtMildLCBhbGwueD1UUlVFKQ0KDQojI0NhbGN1bGF0ZSBMaW5lYXIgRXh0ZW5zaW9uIChjbSkNCkdyb3d0aF9UUDEuMiRFeHRfY208LUdyb3d0aF9UUDEuMiRUTC5UUDJfY20tR3Jvd3RoX1RQMS4yJFRMLlRQMV9jbQ0KDQojI0NhbGN1bGF0ZSBHcm93dGhfVFAxLjIgUmF0ZSAoY20vZGF5KQ0KR3Jvd3RoX1RQMS4yJFRMRV9jbS5kYXk8LUdyb3d0aF9UUDEuMiRFeHRfY20vR3Jvd3RoX1RQMS4yJFRQMS4yX2RheXMNCg0KYGBgDQoNCg0KIyMjIyBEYXRhIFFDDQpgYGB7cn0NCiMjUmVtb3ZlIENvcmFscyBub3QgTWVhc3VyZWQgaW4gVDEgdG8gVDINCkdyb3d0aF9UUDEuMjwtR3Jvd3RoX1RQMS4yICU+JSBkcm9wX25hKFRMRV9jbS5kYXkpDQoNCiMjU2FtcGxlIFNpemUgcGVyIFNldA0KR3Jvd3RoX1RQMS4yICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KFNldCkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoU2FtcGxlU2l6ZSA9IGxlbmd0aChTZXQpKQ0KDQojI0NoZWNrIGZvciBPdXRsaWVycw0KZ2dwbG90KEdyb3d0aF9UUDEuMiwgYWVzKHg9U2V0LCB5PVRMRV9jbS5kYXkpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KYGBgDQoNClBvdGVudGlhbCBvdXRsaWVycyBoYXZlIGJlZW4gcmUtbWVhc3VyZWQgYW5kIHRoZXJlZm9yZSB3aWxsIGJlIHJldGFpbmVkLiBuPTEwIHBlciBTaXRlLCBHZW5vdHlwZSwgT3JpZ2luIGdyb3VwDQoNCg0KIyMjIENvbXBhcmUgR3Jvd3RoIFJhdGUNCmBgYHtyfQ0KI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChHcm93dGhfVFAxLjIkVExFX2NtLmRheSkNCnNoYXBpcm8udGVzdChHcm93dGhfVFAxLjIkVExFX2NtLmRheSkNCiNOb3Qgbm9ybWFsDQoNCmhpc3QobG9nKEdyb3d0aF9UUDEuMiRUTEVfY20uZGF5KzEpKQ0Kc2hhcGlyby50ZXN0KGxvZyhHcm93dGhfVFAxLjIkVExFX2NtLmRheSsxKSkNCiMjU3RpbGwgbm90IG5vcm1hbA0KDQojI0NvbXBhcmUgZ2VuZXJhbGl6ZWQgbGluZWFyIG1peGVkIGVmZmVjdHMgbW9kZWxzDQpUTEVfVFAxLjIuZ2xtci5nYXVzPC1nbG1lcihUTEVfY20uZGF5fk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAxLjIsIGZhbWlseT1nYXVzc2lhbihsaW5rPSJpZGVudGl0eSIpKQ0KVExFX1RQMS4yLmdsbXIuZ2F1cy5sPC1nbG1lcihUTEVfY20uZGF5fk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAxLjIsIGZhbWlseT1nYXVzc2lhbihsaW5rPSJsb2ciKSkNClRMRV9UUDEuMi5nbG1yLmdhdXMuaTwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMS4yLCBmYW1pbHk9Z2F1c3NpYW4obGluaz0iaW52ZXJzZSIpKQ0KDQpUTEVfVFAxLjIuZ2xtci5nYW0ubDwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMS4yLCBmYW1pbHk9R2FtbWEobGluaz0ibG9nIikpDQpUTEVfVFAxLjIuZ2xtci5nYW0uaTwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMS4yLCBmYW1pbHk9R2FtbWEobGluaz0iaW52ZXJzZSIpKQ0KDQpUTEVfVFAxLjIuZ2xtci5pbnY8LWdsbWVyKFRMRV9jbS5kYXl+T3JpZ2luKlNpdGUrKDF8R2Vub3R5cGUpLCBkYXRhPUdyb3d0aF9UUDEuMiwgZmFtaWx5PWludmVyc2UuZ2F1c3NpYW4obGluaz0iMS9tdV4yIikpDQpUTEVfVFAxLjIuZ2xtci5pbnYubDwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMS4yLCBmYW1pbHk9aW52ZXJzZS5nYXVzc2lhbihsaW5rPSJsb2ciKSkNClRMRV9UUDEuMi5nbG1yLmludi5pPC1nbG1lcihUTEVfY20uZGF5fk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAxLjIsIGZhbWlseT1pbnZlcnNlLmdhdXNzaWFuKGxpbms9ImludmVyc2UiKSkNCg0KQUlDKFRMRV9UUDEuMi5nbG1yLmdhdXMsIFRMRV9UUDEuMi5nbG1yLmdhdXMubCwgVExFX1RQMS4yLmdsbXIuZ2F1cy5pLCBUTEVfVFAxLjIuZ2xtci5nYW0ubCwgVExFX1RQMS4yLmdsbXIuZ2FtLmksIFRMRV9UUDEuMi5nbG1yLmludiwgVExFX1RQMS4yLmdsbXIuaW52LmwsIFRMRV9UUDEuMi5nbG1yLmludi5pKQ0KYGBgDQoNCkdhbW1hIGRpc3RyaWJ1dGlvbiB3aXRoIGxvZy1saW5rIGhhcyB0aGUgbG93ZXN0IEFJQy4NCg0KDQpgYGB7cn0NCiMjQ2hlY2sgcmVzaWR1YWxzDQpUTEVfVFAxLjIuZ2xtci5nYW0ubF9yZXMgPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUTEVfVFAxLjIuZ2xtci5nYW0ubCwgcGxvdCA9IEYpDQpwbG90KFRMRV9UUDEuMi5nbG1yLmdhbS5sX3JlcykNCg0KYGBgDQoNCg0KQ29tcGFyZSByZXNpZHVhbHMgYWNyb3NzIG1vZGVscw0KDQpgYGB7cn0NCiMjQ2hlY2sgcmVzaWR1YWxzDQpUTEVfVFAxLjIuZ2xtci5nYXVzLmxfcmVzIDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gVExFX1RQMS4yLmdsbXIuZ2F1cy5sLCBwbG90ID0gRikNCnBsb3QoVExFX1RQMS4yLmdsbXIuZ2F1cy5sX3JlcykNCg0KYGBgDQoNCkNvbXBhcmUgd2l0aCBsb2crMSB0cmFuc2Zvcm1lZCBsbWVyIG1vZGVsDQoNCiMjIyMgTE1FUiBNb2RlbA0KYGBge3J9DQojI01vZGVsIHdpdGggbG9nICsxIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUTEVfVFAxLjIubG1lPC1sbWVyKGxvZyhUTEVfY20uZGF5KzEpfk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAxLjIpDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUTEVfVFAxLjIubG1lX3JlcyA8LSBzaW11bGF0ZVJlc2lkdWFscyhmaXR0ZWRNb2RlbCA9IFRMRV9UUDEuMi5sbWUsIHBsb3QgPSBGKQ0KcGxvdChUTEVfVFAxLjIubG1lX3JlcykNCmBgYA0KQmV0dGVyIHJlc2lkdWFscyB3aXRoIHRoZSBsb2crMSB0cmFuc2Zvcm1lZCBsbWVyIG1vZGVsLg0KDQoNCmBgYHtyfQ0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRMRV9UUDEuMi5sbWUpDQoNCmV0YV9zcXVhcmVkKFRMRV9UUDEuMi5sbWUpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUTEVfVFAxLjIucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVExFX1RQMS4yLmxtZSkkY29lZmZpY2llbnRzWy0xLF0pDQpUTEVfVFAxLjIucmVzJFByZWRpY3RvcjwtYygiT3JpZ2luIiwgIlNpdGUiLCAiT3JpZ2luIHggU2l0ZSIpDQpUTEVfVFAxLjIucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRMRV9UUDEuMi5sbWUpJEV0YTIpDQpUTEVfVFAxLjIucmVzJFJlc3BvbnNlPC1yZXAoIkdyb3d0aCIsIG5yb3coVExFX1RQMS4yLnJlcykpDQpUTEVfVFAxLjIucmVzJFRpbWVwb2ludDwtcmVwKCJUUDFfMiIsIG5yb3coVExFX1RQMS4yLnJlcykpDQoNCmBgYA0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiMjUGFpcndpc2UgQ29tcGFyaXNvbnMgb2YgSW50ZXJlc3QNCiNOYXRpdmUgdnMgVHJhbnNwbGFudCB3aXRoaW4gYSBTaXRlDQpUTEUucGFpcl9UUDEuMjwtZW1tZWFucyhUTEVfVFAxLjIubG1lLCBwYWlyd2lzZX5PcmlnaW4gfCBTaXRlKQ0KVExFLnBhaXJfVFAxLjINCg0KI0NhbGN1bGF0ZSBzdGFuZGFyZGl6ZWQgZWZmZWN0IHNpemVzIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KVExFLnBhaXIuZXNfVFAxLjI8LWRhdGEuZnJhbWUoZWZmX3NpemUoVExFLnBhaXJfVFAxLjIsIHNpZ21hPXNpZ21hKFRMRV9UUDEuMi5sbWUpLCBlZGY9ZGYucmVzaWR1YWwoVExFX1RQMS4yLmxtZSkpKQ0KVExFLnBhaXIuZXNfVFAxLjINClRMRS5wYWlyLmVzX1RQMS4yPC1UTEUucGFpci5lc19UUDEuMiAlPiUgZHBseXI6OnJlbmFtZShjb250cmFzdC5zZSA9IGNvbnRyYXN0LCBTRS5lcyA9IFNFLCBkZi5lcyA9IGRmKQ0KDQojI1NhdmUgUmVzdWx0cw0KVExFLnBhaXJfVFAxLjIucmVzPC1tZXJnZShkYXRhLmZyYW1lKFRMRS5wYWlyX1RQMS4yJGNvbnRyYXN0cyksIFRMRS5wYWlyLmVzX1RQMS4yWywtYygxKV0pDQpUTEUucGFpcl9UUDEuMi5yZXMkUmVzcG9uc2U8LXJlcCgiR3Jvd3RoIiwgbnJvdyhUTEUucGFpcl9UUDEuMi5yZXMpKQ0KVExFLnBhaXJfVFAxLjIucmVzJFRpbWVQPC1yZXAoIlRQMV8yIiwgbnJvdyhUTEUucGFpcl9UUDEuMi5yZXMpKQ0KDQojI0FkZCBTaWduaWZpY2FuY2UgbGV2ZWxzDQpUTEUucGFpcl9UUDEuMi5yZXMkU2lnPC1pZmVsc2UoVExFLnBhaXJfVFAxLjIucmVzJHAudmFsdWU8MC4wMDEsICIqKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRMRS5wYWlyX1RQMS4yLnJlcyRwLnZhbHVlPDAuMDEsICIqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRMRS5wYWlyX1RQMS4yLnJlcyRwLnZhbHVlPDAuMDUsICIqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRMRS5wYWlyX1RQMS4yLnJlcyRwLnZhbHVlPDAuMSwgIi0iLCBOQSkpKSkNClRMRS5wYWlyX1RQMS4yLnJlcw0KYGBgDQoNCg0KIyMjIyBQbG90IEdyb3d0aCBUUCAxIHRvIDINCmBgYHtyIFBsb3QgR3Jvd3RoIFJhdGUgVFAxIHRvIDJ9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBPcmlnaW4NClRQMS4yX0dyb3d0aC5zdW08LXN1bW1hcnlTRShHcm93dGhfVFAxLjIsIG1lYXN1cmV2YXI9IlRMRV9jbS5kYXkiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIEdyb3d0aCBSYXRlIGFjcm9zcyBUcmVhdG1lbnRzDQpUUDEuMl9Hcm93dGgucGxvdDwtZ2dwbG90KFRQMS4yX0dyb3d0aC5zdW0sIGFlcyh4PVNpdGUsIHk9VExFX2NtLmRheSwgY29sb3VyPVNpdGUuT3JpZykpICsgDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPU9yaWcuY29sb3JzLm8pKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVRMRV9jbS5kYXktc2UsIHltYXg9VExFX2NtLmRheStzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIE9yaWdpbiIsIHk9ZXhwcmVzc2lvbihwYXN0ZSgnR3Jvd3RoIFJhdGUgKGNtIGRheSdeLTEqIikiKSksIGNvbG91cj0iT3JpZ2luIikrDQogIHlsaW0oMCwgMC4yNSkrDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0yLCB5PTAuMjQsIGxhYmVsPSIqIiwgc2l6ZT1zaWcuc3osIGZvbnRmYWNlPSJib2xkIikrDQogIGdlb21fYnJhY2tldCh4bWluPTEsIHhtYXg9MiwgeS5wb3NpdGlvbj0wLjAxLCBsYWJlbC5zaXplPWxldmVscy5zeiwgbGFiZWw9IioqIiwgaW5oZXJpdC5hZXMgPSBGQUxTRSk7IFRQMS4yX0dyb3d0aC5wbG90DQpgYGANCg0KDQojIyMgUGVyY2VudCBEaWZmZXJlbmNlIGluIEdyb3d0aCBSYXRlcw0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBHZW5vdHlwZSwgT3JpZ2luLCBhbmQgU2l0ZQ0KVFAxLjJfR3Jvd3RoLnN1bTwtc3VtbWFyeVNFKEdyb3d0aF9UUDEuMiwgbWVhc3VyZXZhcj0iVExFX2NtLmRheSIsIGdyb3VwdmFycz1jKCJHZW5vdHlwZSIsICJPcmlnaW4iLCAiU2l0ZSIpLCBuYS5ybT1UUlVFKQ0KDQojI0NhbGN1bGF0ZSBQZXJjZW50IERpZmZlcmVuY2UgYmV0d2VlbiBOYXRpdmUgYW5kIFRyYW5zcGxhbnQgYnkgR2Vub3R5cGUNClRQMS4yX0dyb3d0aC5kaWY8LVRQMS4yX0dyb3d0aC5zdW1bd2hpY2goVFAxLjJfR3Jvd3RoLnN1bSRPcmlnaW49PSJOYXRpdmUiKSwgYygxLDMsNSldDQpUUDEuMl9Hcm93dGguZGlmPC1UUDEuMl9Hcm93dGguZGlmICU+JSBkcGx5cjo6cmVuYW1lKFRMRV9OID0gVExFX2NtLmRheSkNClRQMS4yX0dyb3d0aC5kaWYkVExFX1Q8LVRQMS4yX0dyb3d0aC5zdW0kVExFX2NtLmRheVt3aGljaChUUDEuMl9Hcm93dGguc3VtJE9yaWdpbj09IlRyYW5zcGxhbnQiKV0NCg0KIyNTUw0KVFAxLjJfR3Jvd3RoLmRpZl9TUzwtc3Vic2V0KFRQMS4yX0dyb3d0aC5kaWYsIFNpdGU9PSJTUyIpDQpUUDEuMl9Hcm93dGguZGlmX1NTJFBlcmMuSW5jPC0oKFRQMS4yX0dyb3d0aC5kaWZfU1MkVExFX04tVFAxLjJfR3Jvd3RoLmRpZl9TUyRUTEVfVCkvVFAxLjJfR3Jvd3RoLmRpZl9TUyRUTEVfVCkqMTAwDQpUUDEuMl9Hcm93dGguZGlmX1NTDQoNCiMjTWVhbiBhbmQgU3RhbmRhcmQgRXJyb3INCm1lYW4oVFAxLjJfR3Jvd3RoLmRpZl9TUyRQZXJjLkluYykNCnN0ZC5lcnJvcihUUDEuMl9Hcm93dGguZGlmX1NTJFBlcmMuSW5jKQ0KDQojI0tMDQpUUDEuMl9Hcm93dGguZGlmX0tMPC1zdWJzZXQoVFAxLjJfR3Jvd3RoLmRpZiwgU2l0ZT09IktMIikNClRQMS4yX0dyb3d0aC5kaWZfS0wkUGVyYy5JbmM8LSgoVFAxLjJfR3Jvd3RoLmRpZl9LTCRUTEVfTi1UUDEuMl9Hcm93dGguZGlmX0tMJFRMRV9UKS9UUDEuMl9Hcm93dGguZGlmX0tMJFRMRV9UKSoxMDANClRQMS4yX0dyb3d0aC5kaWZfS0wNCg0KIyNNZWFuIGFuZCBTdGFuZGFyZCBFcnJvcg0KbWVhbihUUDEuMl9Hcm93dGguZGlmX0tMJFBlcmMuSW5jKQ0Kc3RkLmVycm9yKFRQMS4yX0dyb3d0aC5kaWZfS0wkUGVyYy5JbmMpDQoNCg0KYGBgDQoNCg0KIyMjIEdyb3d0aCBSYXRlIFRQMyB0byBUUDQNCg0KIyMjIyBDYWxjdWxhdGUgRGF5cw0KYGBge3J9DQojI1N1YnNldCBEYXRlcyBmb3IgVFAgMyBhbmQgVFAgNCBHcm93dGgNCkdyb3d0aC5EYXRlc19UUDMuNDwtc3Vic2V0KERhdGVzLCBUYXNrPT0iR3Jvd3RoIiAmIFRpbWVQPT0iVFAzIiB8DQogICAgICAgICAgICAgICAgICAgICAgIFRhc2s9PSJHcm93dGgiICYgVGltZVA9PSJUUDQiICkNCg0KIyNDb252ZXJ0IHRvIFdpZGUgZm9ybWF0DQpHcm93dGguRGF0ZXNfVFAzLjQ8LUdyb3d0aC5EYXRlc19UUDMuNCAlPiUgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBUaW1lUCwgdmFsdWVzX2Zyb20gPSBEYXRlKQ0KDQojI0NhbGN1bGF0ZSBOdW1iZXIgb2YgRGF5cw0KI1RQIDMgdG8gVFA0DQpHcm93dGguRGF0ZXNfVFAzLjQkVFAzLjRfZGF5czwtdGltZV9sZW5ndGgoR3Jvd3RoLkRhdGVzX1RQMy40JFRQNC1Hcm93dGguRGF0ZXNfVFAzLjQkVFAzLCB1bml0PSJkYXlzIikNCg0KYGBgDQoNCg0KIyMjIyBDYWxjdWxhdGUgVG90YWwgTGluZWFyIEV4dGVuc2lvbg0KYGBge3J9DQojI01lcmdlIExlbmd0aCBEYXRhIHdpdGggR3Jvd3RoIERhdGVzDQojTWVyZ2VzIGJ5IFNpdGUgY29sdW1uDQojQWRkcyBUUDMuNF9kYXlzIGNvbHVtbg0KR3Jvd3RoX1RQMy40PC1tZXJnZShMZW5ndGgsIEdyb3d0aC5EYXRlc19UUDMuNFssYygtMildLCBhbGwueD1UUlVFKQ0KDQojI0NhbGN1bGF0ZSBMaW5lYXIgRXh0ZW5zaW9uIChjbSkNCkdyb3d0aF9UUDMuNCRFeHRfY208LUdyb3d0aF9UUDMuNCRUTC5UUDRfY20tR3Jvd3RoX1RQMy40JFRMLlRQM19jbQ0KDQojI0NhbGN1bGF0ZSBHcm93dGhfVFAzLjQgUmF0ZSAoY20vZGF5KQ0KR3Jvd3RoX1RQMy40JFRMRV9jbS5kYXk8LUdyb3d0aF9UUDMuNCRFeHRfY20vR3Jvd3RoX1RQMy40JFRQMy40X2RheXMNCg0KYGBgDQoNCg0KIyMjIyBEYXRhIFFDDQpgYGB7cn0NCiMjUmVtb3ZlIENvcmFscyBub3QgTWVhc3VyZWQgaW4gVDEgdG8gVDINCkdyb3d0aF9UUDMuNDwtR3Jvd3RoX1RQMy40ICU+JSBkcm9wX25hKFRMRV9jbS5kYXkpDQoNCiMjU2FtcGxlIFNpemUgcGVyIFNldA0KR3Jvd3RoX1RQMy40ICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KFNldCkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoU2FtcGxlU2l6ZSA9IGxlbmd0aChTZXQpKQ0KDQojI0NoZWNrIGZvciBPdXRsaWVycw0KZ2dwbG90KEdyb3d0aF9UUDMuNCwgYWVzKHg9U2V0LCB5PVRMRV9jbS5kYXkpKSArIA0KICBnZW9tX2JveHBsb3QoYWxwaGE9MC41LCBzaGFwZT0yLCBvdXRsaWVyLnNoYXBlID0gTkEpKw0KICBnZW9tX2ppdHRlcihzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KYGBgDQoNCg0KIyMjIENvbXBhcmUgR3Jvd3RoIFJhdGUNCmBgYHtyfQ0KI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChHcm93dGhfVFAzLjQkVExFX2NtLmRheSkNCnNoYXBpcm8udGVzdChHcm93dGhfVFAzLjQkVExFX2NtLmRheSkNCiNOb3Qgbm9ybWFsDQoNCmhpc3QobG9nKEdyb3d0aF9UUDMuNCRUTEVfY20uZGF5KzEpKQ0Kc2hhcGlyby50ZXN0KGxvZyhHcm93dGhfVFAzLjQkVExFX2NtLmRheSsxKSkNCiMjU3RpbGwgbm90IG5vcm1hbA0KDQojI0NvbXBhcmUgZ2VuZXJhbGl6ZWQgbGluZWFyIG1peGVkIGVmZmVjdHMgbW9kZWxzDQpUTEVfVFAzLjQuZ2xtci5nYXVzPC1nbG1lcihUTEVfY20uZGF5fk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAzLjQsIGZhbWlseT1nYXVzc2lhbihsaW5rPSJpZGVudGl0eSIpKQ0KVExFX1RQMy40LmdsbXIuZ2F1cy5sPC1nbG1lcihUTEVfY20uZGF5fk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAzLjQsIGZhbWlseT1nYXVzc2lhbihsaW5rPSJsb2ciKSkNClRMRV9UUDMuNC5nbG1yLmdhdXMuaTwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMy40LCBmYW1pbHk9Z2F1c3NpYW4obGluaz0iaW52ZXJzZSIpKQ0KDQpUTEVfVFAzLjQuZ2xtci5nYW0ubDwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMy40LCBmYW1pbHk9R2FtbWEobGluaz0ibG9nIikpDQpUTEVfVFAzLjQuZ2xtci5nYW0uaTwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMy40LCBmYW1pbHk9R2FtbWEobGluaz0iaW52ZXJzZSIpKQ0KDQpUTEVfVFAzLjQuZ2xtci5pbnY8LWdsbWVyKFRMRV9jbS5kYXl+T3JpZ2luKlNpdGUrKDF8R2Vub3R5cGUpLCBkYXRhPUdyb3d0aF9UUDMuNCwgZmFtaWx5PWludmVyc2UuZ2F1c3NpYW4obGluaz0iMS9tdV4yIikpDQpUTEVfVFAzLjQuZ2xtci5pbnYubDwtZ2xtZXIoVExFX2NtLmRheX5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9R3Jvd3RoX1RQMy40LCBmYW1pbHk9aW52ZXJzZS5nYXVzc2lhbihsaW5rPSJsb2ciKSkNClRMRV9UUDMuNC5nbG1yLmludi5pPC1nbG1lcihUTEVfY20uZGF5fk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAzLjQsIGZhbWlseT1pbnZlcnNlLmdhdXNzaWFuKGxpbms9ImludmVyc2UiKSkNCg0KQUlDKFRMRV9UUDMuNC5nbG1yLmdhdXMsIFRMRV9UUDMuNC5nbG1yLmdhdXMubCwgVExFX1RQMy40LmdsbXIuZ2F1cy5pLCBUTEVfVFAzLjQuZ2xtci5nYW0ubCwgVExFX1RQMy40LmdsbXIuZ2FtLmksIFRMRV9UUDMuNC5nbG1yLmludiwgVExFX1RQMy40LmdsbXIuaW52LmwsIFRMRV9UUDMuNC5nbG1yLmludi5pKQ0KYGBgDQoNCkdhbW1hIGRpc3RyaWJ1dGlvbiB3aXRoIGxvZy1saW5rIGhhcyB0aGUgbG93ZXN0IEFJQy4NCg0KDQpgYGB7cn0NCiMjQ2hlY2sgcmVzaWR1YWxzDQpUTEVfVFAzLjQuZ2xtci5nYW0ubF9yZXMgPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUTEVfVFAzLjQuZ2xtci5nYW0ubCwgcGxvdCA9IEYpDQpwbG90KFRMRV9UUDMuNC5nbG1yLmdhbS5sX3JlcykNCg0KYGBgDQoNCg0KQ29tcGFyZSByZXNpZHVhbHMgYWNyb3NzIG1vZGVscw0KDQpgYGB7cn0NCiMjQ2hlY2sgcmVzaWR1YWxzDQpUTEVfVFAzLjQuZ2xtci5nYXVzLmxfcmVzIDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gVExFX1RQMy40LmdsbXIuZ2F1cy5sLCBwbG90ID0gRikNCnBsb3QoVExFX1RQMy40LmdsbXIuZ2F1cy5sX3JlcykNCg0KYGBgDQoNCkNvbXBhcmUgd2l0aCBsb2crMSB0cmFuc2Zvcm1lZCBsbWVyIG1vZGVsDQoNCiMjIyMgTE1FUiBNb2RlbA0KYGBge3J9DQojI01vZGVsIHdpdGggbG9nICsxIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUTEVfVFAzLjQubG1lPC1sbWVyKGxvZyhUTEVfY20uZGF5KzEpfk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1Hcm93dGhfVFAzLjQpDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUTEVfVFAzLjQubG1lX3JlcyA8LSBzaW11bGF0ZVJlc2lkdWFscyhmaXR0ZWRNb2RlbCA9IFRMRV9UUDMuNC5sbWUsIHBsb3QgPSBGKQ0KcGxvdChUTEVfVFAzLjQubG1lX3JlcykNCmBgYA0KQmV0dGVyIHJlc2lkdWFscyB3aXRoIHRoZSBsb2crMSB0cmFuc2Zvcm1lZCBsbWVyIG1vZGVsLg0KDQoNCmBgYHtyfQ0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRMRV9UUDMuNC5sbWUpDQoNCmV0YV9zcXVhcmVkKFRMRV9UUDMuNC5sbWUpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUTEVfVFAzLjQucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVExFX1RQMy40LmxtZSkkY29lZmZpY2llbnRzWy0xLF0pDQpUTEVfVFAzLjQucmVzJFByZWRpY3RvcjwtYygiT3JpZ2luIiwgIlNpdGUiLCAiT3JpZ2luIHggU2l0ZSIpDQpUTEVfVFAzLjQucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRMRV9UUDMuNC5sbWUpJEV0YTIpDQpUTEVfVFAzLjQucmVzJFJlc3BvbnNlPC1yZXAoIkdyb3d0aCIsIG5yb3coVExFX1RQMy40LnJlcykpDQpUTEVfVFAzLjQucmVzJFRpbWVwb2ludDwtcmVwKCJUUDNfNCIsIG5yb3coVExFX1RQMy40LnJlcykpDQoNCmBgYA0KDQojIyMjIFBhaXJ3aXNlIA0KYGBge3J9DQojI1BhaXJ3aXNlIENvbXBhcmlzb25zIG9mIEludGVyZXN0DQojTmF0aXZlIHZzIFRyYW5zcGxhbnQgd2l0aGluIGEgU2l0ZQ0KVExFLnBhaXJfVFAzLjQ8LWVtbWVhbnMoVExFX1RQMy40LmxtZSwgcGFpcndpc2V+T3JpZ2luIHwgU2l0ZSkNClRMRS5wYWlyX1RQMy40DQoNCiNDYWxjdWxhdGUgc3RhbmRhcmRpemVkIGVmZmVjdCBzaXplcyBmb3IgcGFpcndpc2UgY29tcGFyaXNvbnMNClRMRS5wYWlyLmVzX1RQMy40PC1kYXRhLmZyYW1lKGVmZl9zaXplKFRMRS5wYWlyX1RQMy40LCBzaWdtYT1zaWdtYShUTEVfVFAzLjQubG1lKSwgZWRmPWRmLnJlc2lkdWFsKFRMRV9UUDMuNC5sbWUpKSkNClRMRS5wYWlyLmVzX1RQMy40DQpUTEUucGFpci5lc19UUDMuNDwtVExFLnBhaXIuZXNfVFAzLjQgJT4lIGRwbHlyOjpyZW5hbWUoY29udHJhc3Quc2UgPSBjb250cmFzdCwgU0UuZXMgPSBTRSwgZGYuZXMgPSBkZikNCg0KIyNTYXZlIFJlc3VsdHMNClRMRS5wYWlyX1RQMy40LnJlczwtbWVyZ2UoZGF0YS5mcmFtZShUTEUucGFpcl9UUDMuNCRjb250cmFzdHMpLCBUTEUucGFpci5lc19UUDMuNFssLWMoMSldKQ0KVExFLnBhaXJfVFAzLjQucmVzJFJlc3BvbnNlPC1yZXAoIkdyb3d0aCIsIG5yb3coVExFLnBhaXJfVFAzLjQucmVzKSkNClRMRS5wYWlyX1RQMy40LnJlcyRUaW1lUDwtcmVwKCJUUDNfNCIsIG5yb3coVExFLnBhaXJfVFAzLjQucmVzKSkNCg0KIyNBZGQgU2lnbmlmaWNhbmNlIGxldmVscw0KVExFLnBhaXJfVFAzLjQucmVzJFNpZzwtaWZlbHNlKFRMRS5wYWlyX1RQMy40LnJlcyRwLnZhbHVlPDAuMDAxLCAiKioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUTEUucGFpcl9UUDMuNC5yZXMkcC52YWx1ZTwwLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUTEUucGFpcl9UUDMuNC5yZXMkcC52YWx1ZTwwLjA1LCAiKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUTEUucGFpcl9UUDMuNC5yZXMkcC52YWx1ZTwwLjEsICItIiwgTkEpKSkpDQpUTEUucGFpcl9UUDMuNC5yZXMNCmBgYA0KDQoNCiMjIyMgUGxvdCBHcm93dGggVFAgMyB0byA0DQpgYGB7ciBQbG90IEdyb3d0aCBSYXRlIFRQMyB0byA0fQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDMuNF9Hcm93dGguc3VtPC1zdW1tYXJ5U0UoR3Jvd3RoX1RQMy40LCBtZWFzdXJldmFyPSJUTEVfY20uZGF5IiwgZ3JvdXB2YXJzPWMoIlNpdGUiLCAiT3JpZ2luIiwgIlNpdGUuT3JpZyIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBHcm93dGggUmF0ZSBhY3Jvc3MgVHJlYXRtZW50cw0KVFAzLjRfR3Jvd3RoLnBsb3Q8LWdncGxvdChUUDMuNF9Hcm93dGguc3VtLCBhZXMoeD1TaXRlLCB5PVRMRV9jbS5kYXksIGNvbG91cj1TaXRlLk9yaWcpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1UTEVfY20uZGF5LXNlLCB5bWF4PVRMRV9jbS5kYXkrc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PSJTaXRlIGFuZCBPcmlnaW4iLCB5PWV4cHJlc3Npb24ocGFzdGUoJ0dyb3d0aCBSYXRlIChjbSBkYXknXi0xKiIpIikpLCBjb2xvdXI9Ik9yaWdpbiIpKw0KICB5bGltKDAsIDAuMjUpKw0KICBhbm5vdGF0ZSgidGV4dCIsIHg9MSwgeT0wLjIyLCBsYWJlbD0iKiIsIHNpemU9c2lnLnN6LCBmb250ZmFjZT0iYm9sZCIpKw0KICBhbm5vdGF0ZSgidGV4dCIsIHg9MiwgeT0wLjE4LCBsYWJlbD0iKioiLCBzaXplPXNpZy5zeiwgZm9udGZhY2U9ImJvbGQiKSsNCiAgZ2VvbV9icmFja2V0KHhtaW49MSwgeG1heD0yLCB5LnBvc2l0aW9uPTAuMDEsIGxhYmVsLnNpemU9bGV2ZWxzLnN6LCBsYWJlbD0iKioqIiwgaW5oZXJpdC5hZXMgPSBGQUxTRSk7IFRQMy40X0dyb3d0aC5wbG90DQpgYGANCg0KDQojIyMgUGVyY2VudCBEaWZmZXJlbmNlIGluIEdyb3d0aCBSYXRlcw0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBHZW5vdHlwZSwgT3JpZ2luLCBhbmQgU2l0ZQ0KVFAzLjRfR3Jvd3RoLnN1bTwtc3VtbWFyeVNFKEdyb3d0aF9UUDMuNCwgbWVhc3VyZXZhcj0iVExFX2NtLmRheSIsIGdyb3VwdmFycz1jKCJHZW5vdHlwZSIsICJPcmlnaW4iLCAiU2l0ZSIpLCBuYS5ybT1UUlVFKQ0KDQojI0NhbGN1bGF0ZSBQZXJjZW50IERpZmZlcmVuY2UgYmV0d2VlbiBOYXRpdmUgYW5kIFRyYW5zcGxhbnQgYnkgR2Vub3R5cGUNClRQMy40X0dyb3d0aC5kaWY8LVRQMy40X0dyb3d0aC5zdW1bd2hpY2goVFAzLjRfR3Jvd3RoLnN1bSRPcmlnaW49PSJOYXRpdmUiKSwgYygxLDMsNSldDQpUUDMuNF9Hcm93dGguZGlmPC1UUDMuNF9Hcm93dGguZGlmICU+JSBkcGx5cjo6cmVuYW1lKFRMRV9OID0gVExFX2NtLmRheSkNClRQMy40X0dyb3d0aC5kaWYkVExFX1Q8LVRQMy40X0dyb3d0aC5zdW0kVExFX2NtLmRheVt3aGljaChUUDMuNF9Hcm93dGguc3VtJE9yaWdpbj09IlRyYW5zcGxhbnQiKV0NCg0KIyNTUw0KVFAzLjRfR3Jvd3RoLmRpZl9TUzwtc3Vic2V0KFRQMy40X0dyb3d0aC5kaWYsIFNpdGU9PSJTUyIpDQpUUDMuNF9Hcm93dGguZGlmX1NTJFBlcmMuSW5jPC0oKFRQMy40X0dyb3d0aC5kaWZfU1MkVExFX1QtVFAzLjRfR3Jvd3RoLmRpZl9TUyRUTEVfTikvVFAzLjRfR3Jvd3RoLmRpZl9TUyRUTEVfTikqMTAwDQpUUDMuNF9Hcm93dGguZGlmX1NTDQoNCiMjTWVhbiBhbmQgU3RhbmRhcmQgRXJyb3INCm1lYW4oVFAzLjRfR3Jvd3RoLmRpZl9TUyRQZXJjLkluYykNCnN0ZC5lcnJvcihUUDMuNF9Hcm93dGguZGlmX1NTJFBlcmMuSW5jKQ0KDQojI0tMDQpUUDMuNF9Hcm93dGguZGlmX0tMPC1zdWJzZXQoVFAzLjRfR3Jvd3RoLmRpZiwgU2l0ZT09IktMIikNClRQMy40X0dyb3d0aC5kaWZfS0wkUGVyYy5JbmM8LSgoVFAzLjRfR3Jvd3RoLmRpZl9LTCRUTEVfTi1UUDMuNF9Hcm93dGguZGlmX0tMJFRMRV9UKS9UUDMuNF9Hcm93dGguZGlmX0tMJFRMRV9UKSoxMDANClRQMy40X0dyb3d0aC5kaWZfS0wNCg0KIyNNZWFuIGFuZCBTdGFuZGFyZCBFcnJvcg0KbWVhbihUUDMuNF9Hcm93dGguZGlmX0tMJFBlcmMuSW5jKQ0Kc3RkLmVycm9yKFRQMy40X0dyb3d0aC5kaWZfS0wkUGVyYy5JbmMpDQoNCmBgYA0KDQoNCiMgV3JpdGUgT3V0IEdyb3d0aCBEYXRhDQpgYGB7cn0NCiMjR3Jvd3RoIERhdGEgZGF0YWZyYW1lDQpHcm93dGhEYXRhPC1Hcm93dGhfVFAxLjINCg0KIyNTcGVjaWZ5IFRpbWVwb2ludHMNCkdyb3d0aERhdGE8LUdyb3d0aERhdGEgJT4lIGRwbHlyOjpyZW5hbWUoVFAxLjJfRXh0X2NtID0gRXh0X2NtLCBUUDEuMl9UTEVfY20uZGF5ID0gVExFX2NtLmRheSkNCg0KIyNNZXJnZSB3aXRoIFRpbWVwb2ludHMgMyB0byA0DQpHcm93dGhEYXRhPC1tZXJnZShHcm93dGhEYXRhLCBHcm93dGhfVFAzLjQsIGFsbD1UUlVFKQ0KDQojI1NwZWNpZnkgVGltZXBvaW50cw0KR3Jvd3RoRGF0YTwtR3Jvd3RoRGF0YSAlPiUgZHBseXI6OnJlbmFtZShUUDMuNF9FeHRfY20gPSBFeHRfY20sIFRQMy40X1RMRV9jbS5kYXkgPSBUTEVfY20uZGF5KQ0KDQojI0dyb3d0aCBEYXRhDQp3cml0ZS5jc3YoR3Jvd3RoRGF0YSwgIk91dHB1dHMvR3Jvd3RoRGF0YS5jc3YiLCByb3cubmFtZXM9RkFMU0UpDQpgYGANCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlDQoNCiMjIyBQZXJjZW50IFJldGVudGlvbg0KDQojIyMjIFN1YnNldCBUaGVybWFsIEFzc2F5IERhdGEgYnkgVHJlYXRtZW50DQpgYGB7cn0NCiMjQ29udHJvbA0KVGhlcm1fQzwtc3Vic2V0KFRoZXJtYWwsIFRyZWF0PT0iQyIpDQoNCiMjSGVhdGVkDQpUaGVybV9IPC1zdWJzZXQoVGhlcm1hbCwgVHJlYXQ9PSJIIikNCmBgYA0KDQoNCiMjIyMgQ2FsY3VsYXRlIFBlcmNlbnQgUmV0ZW50aW9uDQpDYWxjdWxhdGluZyByZXRlbnRpb24gYXMgcHJvcG9ydGlvbiByZW1haW5pbmcgcmVsYXRpdmUgdG8gY29ycmVzcG9uZGluZyBjb250cm9sIGxldmVscyAoMC0xKSBmb3IgZWFjaCBzaXRlIGFuZCBnZW5vdHlwZSBhdCBlYWNoIHRpbWVwb2ludC4NCmBgYHtyfQ0KIyNDYWxjdWxhdGUgYXZlcmFnZXMgZm9yIENvbnRyb2wgVHJlYXRtZW50IGZvciBlYWNoIFNpdGUsIEdlbm90eXBlLCBhbmQgVGltZXBvaW50IA0KVGhlcm1fQzwtbmEub21pdChUaGVybV9DKQ0KbmFtZXMoVGhlcm1fQykNClRoZXJtX0MuYTwtYWdncmVnYXRlKFRoZXJtX0NbLGMoMTM6MTUpXSwgbGlzdChUaGVybV9DJFNpdGUsIFRoZXJtX0MkR2Vub3R5cGUsIFRoZXJtX0MkVGltZVAsIFRoZXJtX0MkT3JpZ2luKSwgbWVhbiwgbmEuYWN0aW9uID0gbmEub21pdCkNCm5hbWVzKFRoZXJtX0MuYSlbMTo0XTwtYygiU2l0ZSIsICJHZW5vdHlwZSIsICJUaW1lUCIsICJPcmlnaW4iKQ0KbmFtZXMoVGhlcm1fQy5hKVs1OjddPC1wYXN0ZShuYW1lcyhUaGVybV9DLmEpWzU6N10sICJDIiwgc2VwPSJfIikNCg0KIyNNZXJnZSBDb250cm9sIEF2ZXJhZ2VzIHdpdGggSGVhdGVkIFNhbXBsZXMNCiNNZXJnZXMgYnkgU2l0ZSwgR2Vub3R5cGUsIGFuZCBUaW1lcG9pbnQNClRoZXJtX0g8LW1lcmdlKFRoZXJtX0gsIFRoZXJtX0MuYSwgYWxsLng9VFJVRSApDQoNCiMjQ2FsY3VsYXRlIFByb3BvcnRpb24gUmV0YWluZWQgZm9yIGVhY2ggQmxlYWNoaW5nIE1ldHJpYyByZWxhdGl2ZSB0byBDb250cm9sDQpUaGVybV9IJENobC5wcm9wPC1yb3VuZCgoVGhlcm1fSCRDaGxfdWcuY20yL1RoZXJtX0gkQ2hsX3VnLmNtMl9DKSwgNCkNClRoZXJtX0gkU3ltLnByb3A8LXJvdW5kKChUaGVybV9IJFN5bTEwLjZfY20yL1RoZXJtX0gkU3ltMTAuNl9jbTJfQyksIDQpDQpUaGVybV9IJFBBTS5wcm9wPC1yb3VuZCgoVGhlcm1fSCRGdl9GbS9UaGVybV9IJEZ2X0ZtX0MpLCA0KQ0KDQojI1NldCB2YWx1ZXMgPjEgdG8gMQ0KVGhlcm1fSCRDaGwucHJvcFt3aGljaChUaGVybV9IJENobC5wcm9wPjEpXTwtMS4wMDAwDQpUaGVybV9IJFN5bS5wcm9wW3doaWNoKFRoZXJtX0gkU3ltLnByb3A+MSldPC0xLjAwMDANClRoZXJtX0gkUEFNLnByb3Bbd2hpY2goVGhlcm1fSCRQQU0ucHJvcD4xKV08LTEuMDAwMA0KDQpgYGANCg0KDQojIEluaXRpYWwgSGVhdCBBc3NheSANCg0KYGBge3J9DQojI1N1YnNldCBJbml0aWFsIFRpbWVwb2ludA0KVGhlcm1hbF9JTjwtc3Vic2V0KFRoZXJtYWwsIFRpbWVQPT0iSU4iKQ0KVGhlcm1hbF9JTiRTaXRlLlRyZWF0PC1wYXN0ZShUaGVybWFsX0lOJFNpdGUsIFRoZXJtYWxfSU4kVHJlYXQsIHNlcD0iLiIpDQpUaGVybWFsX0lOJFNpdGUuVHJlYXQ8LWZhY3RvcihUaGVybWFsX0lOJFNpdGUuVHJlYXQsIGxldmVscz1jKCJLTC5DIiwgIktMLkgiLCAiU1MuQyIsICJTUy5IIikpDQoNCg0KVGhlcm1fSU48LXN1YnNldChUaGVybV9ILCBUaW1lUD09IklOIikNCmBgYA0KDQoNCiMjIyBIZWF0ZWQgdnMgQ29udHJvbA0KDQoNCiMjIyMgU3ltYmlvbnRzDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1hbF9JTiRTeW0xMC42X2NtMikNCnNoYXBpcm8udGVzdChUaGVybWFsX0lOJFN5bTEwLjZfY20yKQ0KI05vdCBub3JtYWwNCg0KaGlzdChsb2coVGhlcm1hbF9JTiRTeW0xMC42X2NtMisxKSkNCnNoYXBpcm8udGVzdChsb2coVGhlcm1hbF9JTiRTeW0xMC42X2NtMisxKSkNCiNOb3JtYWwNCg0KIyNNb2RlbA0KI0Z1bmN0aW9uIG9mIFNpdGUgYW5kIFRyZWF0bWVudCwgd2l0aCBHZW5vdHlwZSBhcyBhIFJhbmRvbSBlZmZlY3QNClN5bS5sbWVfSU48LWxtZXIobG9nKFN5bTEwLjZfY20yKzEpflNpdGUqVHJlYXRtZW50KygxfEdlbm90eXBlKSwgZGF0YT1UaGVybWFsX0lOKQ0KDQojI0NoZWNrIHJlc2lkdWFscw0KU3ltLmxtZV9yZXNfSU4gPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBTeW0ubG1lX0lOLCBwbG90ID0gRikNCnBsb3QoU3ltLmxtZV9yZXNfSU4pDQoNCiMjTW9kZWwgcmVzdWx0cw0Kc3VtbWFyeShTeW0ubG1lX0lOKQ0KDQpldGFfc3F1YXJlZChTeW0ubG1lX0lOKQ0KDQplbW1lYW5zKFN5bS5sbWVfSU4sIHBhaXJ3aXNlIH4gU2l0ZSB8IFRyZWF0bWVudCkNCg0KZW1tZWFucyhTeW0ubG1lX0lOLCBwYWlyd2lzZSB+IFRyZWF0bWVudCB8IFNpdGUpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpTeW1fSU4ucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoU3ltLmxtZV9JTikkY29lZmZpY2llbnRzWy0xLF0pDQoNCiMjQWRkIHBhaXJ3aXNlDQpuYW1lcyhTeW1fSU4ucmVzKTwtbmFtZXMoZGF0YS5mcmFtZShlbW1lYW5zKFN5bS5sbWVfSU4sIHBhaXJ3aXNlIH4gU2l0ZSB8IFRyZWF0bWVudCkkY29udHJhc3RzKSlbLWMoMToyKV0NClN5bV9JTi5yZXM8LXJiaW5kKFN5bV9JTi5yZXMsDQpkYXRhLmZyYW1lKHJiaW5kKGVtbWVhbnMoU3ltLmxtZV9JTiwgcGFpcndpc2UgfiBTaXRlIHwgVHJlYXRtZW50KSRjb250cmFzdHNbMV0sIGVtbWVhbnMoU3ltLmxtZV9JTiwgcGFpcndpc2UgfiBTaXRlIHwgVHJlYXRtZW50KSRjb250cmFzdHNbMl0sIGVtbWVhbnMoU3ltLmxtZV9JTiwgcGFpcndpc2UgfiBUcmVhdG1lbnQgfCBTaXRlKSRjb250cmFzdHNbMV0sIGVtbWVhbnMoU3ltLmxtZV9JTiwgcGFpcndpc2UgfiBUcmVhdG1lbnQgfCBTaXRlKSRjb250cmFzdHNbMl0pKVssLWMoMTozKV0pDQoNCiMjTWV0YWRhdGENClN5bV9JTi5yZXMkUHJlZGljdG9yPC1jKCJTaXRlIiwgIlRyZWF0bWVudCIsICJTaXRlIHggVHJlYXRtZW50IiwgIkNvbnRyb2wgU2l0ZSIsICJIZWF0ZWQgU2l0ZSIsICJLTCBUcmVhdG1lbnQiLCAiU1MgVHJlYXRtZW50IikNClN5bV9JTi5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhTeW1fSU4ucmVzKSkNClN5bV9JTi5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoU3ltLmxtZV9JTikkRXRhMiwgcmVwKE5BLCA0KSkNCg0KYGBgDQoNCg0KYGBge3IgUGxvdCBTeW1iaW9udHMgSW5pdGlhbH0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUNCklOX1N5bS5zdW08LXN1bW1hcnlTRShUaGVybWFsX0lOLCBtZWFzdXJldmFyPSJTeW0xMC42X2NtMiIsIGdyb3VwdmFycz1jKCJTaXRlIiwgIlRyZWF0bWVudCIsICJTaXRlLlRyZWF0IiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFN5bWJpb250cyBhY3Jvc3MgVHJlYXRtZW50cw0KSU5fU3ltLnBsb3Q8LWdncGxvdChJTl9TeW0uc3VtLCBhZXMoeD1TaXRlLlRyZWF0LCB5PVN5bTEwLjZfY20yLCBjb2xvdXI9U2l0ZSkpICsgDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPVNpdGUuY29sb3JzLm8pKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVN5bTEwLjZfY20yLXNlLCB5bWF4PVN5bTEwLjZfY20yK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fcG9pbnQoYWVzKHNoYXBlPVRyZWF0bWVudCksIHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPWMoMSwxNikpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIFRyZWF0bWVudCIsIHk9ZXhwcmVzc2lvbihwYXN0ZSgnU3ltYmlvbnQgRGVuc2l0eSAoJyoxMF42LCdjZWxscyBjbSdeLTIqIikiKSksIGNvbG91cj0iU2l0ZSIpKw0KICB5bGltKDAsIDEpKw0KICBhbm5vdGF0ZSgidGV4dCIsIHg9LjYsIHk9MSwgaGp1c3Q9MCwgbGFiZWw9IlNpdGUgKioiLCBzaXplPXNpZy5zeiwgZm9udGZhY2U9ImJvbGQiKSsNCiAgYW5ub3RhdGUoInRleHQiLCB4PS42LCB5PS45NCwgaGp1c3Q9MCwgbGFiZWw9IlRyZWF0bWVudCAqKiIsIHNpemU9c2lnLnN6LCBmb250ZmFjZT0iYm9sZCIpOyBJTl9TeW0ucGxvdA0KYGBgDQoNCg0KIyMjIyBDaGxvcm9waHlsbA0KYGBge3J9DQojQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRoZXJtYWxfSU4kQ2hsX3VnLmNtMikNCnNoYXBpcm8udGVzdChUaGVybWFsX0lOJENobF91Zy5jbTIpDQojTm90IG5vcm1hbA0KDQpoaXN0KGxvZyhUaGVybWFsX0lOJENobF91Zy5jbTIrMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRoZXJtYWxfSU4kQ2hsX3VnLmNtMisxKSkNCiNTdGlsbCBub3Qgbm9ybWFsIGJ1dCBsZXNzIHNrZXdlZA0KDQojI01vZGVsDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgVHJlYXRtZW50LCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KQ2hsLmxtZV9JTjwtbG1lcihsb2coQ2hsX3VnLmNtMisxKX5TaXRlKlRyZWF0bWVudCsoMXxHZW5vdHlwZSksIGRhdGE9VGhlcm1hbF9JTikNCg0KIyNDaGVjayByZXNpZHVhbHMNCkNobC5sbWVfcmVzX0lOIDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gQ2hsLmxtZV9JTiwgcGxvdCA9IEYpDQpwbG90KENobC5sbWVfcmVzX0lOKQ0KDQojI01vZGVsIHJlc3VsdHMNCnN1bW1hcnkoQ2hsLmxtZV9JTikNCg0KZXRhX3NxdWFyZWQoQ2hsLmxtZV9JTikNCg0KZW1tZWFucyhDaGwubG1lX0lOLCBwYWlyd2lzZSB+IFNpdGUgfCBUcmVhdG1lbnQpDQoNCmVtbWVhbnMoQ2hsLmxtZV9JTiwgcGFpcndpc2UgfiBUcmVhdG1lbnQgfCBTaXRlKQ0KDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpDaGxfSU4ucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoQ2hsLmxtZV9JTikkY29lZmZpY2llbnRzWy0xLF0pDQoNCiMjQWRkIHBhaXJ3aXNlDQpuYW1lcyhDaGxfSU4ucmVzKTwtbmFtZXMoZGF0YS5mcmFtZShlbW1lYW5zKENobC5sbWVfSU4sIHBhaXJ3aXNlIH4gU2l0ZSB8IFRyZWF0bWVudCkkY29udHJhc3RzKSlbLWMoMToyKV0NCkNobF9JTi5yZXM8LXJiaW5kKENobF9JTi5yZXMsDQpkYXRhLmZyYW1lKHJiaW5kKGVtbWVhbnMoQ2hsLmxtZV9JTiwgcGFpcndpc2UgfiBTaXRlIHwgVHJlYXRtZW50KSRjb250cmFzdHNbMV0sIGVtbWVhbnMoQ2hsLmxtZV9JTiwgcGFpcndpc2UgfiBTaXRlIHwgVHJlYXRtZW50KSRjb250cmFzdHNbMl0sIGVtbWVhbnMoQ2hsLmxtZV9JTiwgcGFpcndpc2UgfiBUcmVhdG1lbnQgfCBTaXRlKSRjb250cmFzdHNbMV0sIGVtbWVhbnMoQ2hsLmxtZV9JTiwgcGFpcndpc2UgfiBUcmVhdG1lbnQgfCBTaXRlKSRjb250cmFzdHNbMl0pKVssLWMoMTozKV0pDQoNCiMjTWV0YWRhdGENCkNobF9JTi5yZXMkUHJlZGljdG9yPC1jKCJTaXRlIiwgIlRyZWF0bWVudCIsICJTaXRlIHggVHJlYXRtZW50IiwgIkNvbnRyb2wgU2l0ZSIsICJIZWF0ZWQgU2l0ZSIsICJLTCBUcmVhdG1lbnQiLCAiU1MgVHJlYXRtZW50IikNCkNobF9JTi5yZXMkUmVzcG9uc2U8LXJlcCgiQ2hsb3JvcGh5bGwiLCBucm93KENobF9JTi5yZXMpKQ0KQ2hsX0lOLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChDaGwubG1lX0lOKSRFdGEyLCByZXAoTkEsIDQpKQ0KDQpgYGANCg0KDQpgYGB7ciBQbG90IENobG9yb3BoeWxsIEluaXRpYWx9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlDQpJTl9DaGwuc3VtPC1zdW1tYXJ5U0UoVGhlcm1hbF9JTiwgbWVhc3VyZXZhcj0iQ2hsX3VnLmNtMiIsIGdyb3VwdmFycz1jKCJTaXRlIiwgIlRyZWF0bWVudCIsICJTaXRlLlRyZWF0IiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIENobG9yb3BoeWxsIGFjcm9zcyBUcmVhdG1lbnRzDQpJTl9DaGwucGxvdDwtZ2dwbG90KElOX0NobC5zdW0sIGFlcyh4PVNpdGUuVHJlYXQsIHk9Q2hsX3VnLmNtMiwgY29sb3VyPVNpdGUpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1TaXRlLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGxfdWcuY20yLXNlLCB5bWF4PUNobF91Zy5jbTIrc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChhZXMoc2hhcGU9VHJlYXRtZW50KSwgc2l6ZT1wb2ludC5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkrDQogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YygxLDE2KSkrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSkrDQogIGxhYnMoeD0iU2l0ZSBhbmQgVHJlYXRtZW50IiwgeT1leHByZXNzaW9uKHBhc3RlKCdUb3RhbCBDaGxvcm9waHlsbCAoXHUwM0JDZyBjbSdeLTIqIikiKSksIGNvbG91cj0iU2l0ZSIpKw0KICB5bGltKDAsIDEuMjUpKw0KICBhbm5vdGF0ZSgidGV4dCIsIHg9LjYsIHk9MS4yLCBoanVzdD0wLCBsYWJlbD0iU2l0ZSAqKioiLCBzaXplPXNpZy5zeiwgZm9udGZhY2U9ImJvbGQiKSsNCiAgYW5ub3RhdGUoInRleHQiLCB4PS42LCB5PTEuMTIsIGhqdXN0PTAsIGxhYmVsPSJUcmVhdG1lbnQgKioqIiwgc2l6ZT1zaWcuc3osIGZvbnRmYWNlPSJib2xkIikrDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0uNiwgeT0xLjA0LCBoanVzdD0wLCBsYWJlbD0iU2l0ZSB4IFRyZWF0bWVudCAqKiIsIHNpemU9c2lnLnN6LCBmb250ZmFjZT0iYm9sZCIpOyBJTl9DaGwucGxvdA0KYGBgDQoNCg0KIyMjIyBGdkZtDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1hbF9JTiRGdl9GbSkNCnNoYXBpcm8udGVzdChUaGVybWFsX0lOJEZ2X0ZtKQ0KI05vdCBub3JtYWwNCg0KaGlzdChUaGVybWFsX0lOJEZ2X0ZtXjIpDQpzaGFwaXJvLnRlc3QoVGhlcm1hbF9JTiRGdl9GbV4yKQ0KI1N0aWxsIG5vdCBub3JtYWwgYnV0IGxlc3Mgc2tld2VkDQoNCiMjTW9kZWwNCiNGdW5jdGlvbiBvZiBTaXRlIGFuZCBUcmVhdG1lbnQsIHdpdGggR2Vub3R5cGUgYXMgYSBSYW5kb20gZWZmZWN0DQpQQU0ubG1lX0lOPC1sbWVyKEZ2X0ZtXjJ+U2l0ZSpUcmVhdG1lbnQrKDF8R2Vub3R5cGUpLCBkYXRhPVRoZXJtYWxfSU4pDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpQQU0ubG1lX3Jlc19JTiA8LSBzaW11bGF0ZVJlc2lkdWFscyhmaXR0ZWRNb2RlbCA9IFBBTS5sbWVfSU4sIHBsb3QgPSBGKQ0KcGxvdChQQU0ubG1lX3Jlc19JTikNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFBBTS5sbWVfSU4pDQoNCmV0YV9zcXVhcmVkKFBBTS5sbWVfSU4pDQoNCmVtbWVhbnMoUEFNLmxtZV9JTiwgcGFpcndpc2UgfiBTaXRlIHwgVHJlYXRtZW50KQ0KDQplbW1lYW5zKFBBTS5sbWVfSU4sIHBhaXJ3aXNlIH4gVHJlYXRtZW50IHwgU2l0ZSkNCg0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KUEFNX0lOLnJlczwtZGF0YS5mcmFtZShzdW1tYXJ5KFBBTS5sbWVfSU4pJGNvZWZmaWNpZW50c1stMSxdKQ0KDQojI0FkZCBwYWlyd2lzZQ0KbmFtZXMoUEFNX0lOLnJlcyk8LW5hbWVzKGRhdGEuZnJhbWUoZW1tZWFucyhQQU0ubG1lX0lOLCBwYWlyd2lzZSB+IFNpdGUgfCBUcmVhdG1lbnQpJGNvbnRyYXN0cykpWy1jKDE6MildDQpQQU1fSU4ucmVzPC1yYmluZChQQU1fSU4ucmVzLA0KZGF0YS5mcmFtZShyYmluZChlbW1lYW5zKFBBTS5sbWVfSU4sIHBhaXJ3aXNlIH4gU2l0ZSB8IFRyZWF0bWVudCkkY29udHJhc3RzWzFdLCBlbW1lYW5zKFBBTS5sbWVfSU4sIHBhaXJ3aXNlIH4gU2l0ZSB8IFRyZWF0bWVudCkkY29udHJhc3RzWzJdLCBlbW1lYW5zKFBBTS5sbWVfSU4sIHBhaXJ3aXNlIH4gVHJlYXRtZW50IHwgU2l0ZSkkY29udHJhc3RzWzFdLCBlbW1lYW5zKFBBTS5sbWVfSU4sIHBhaXJ3aXNlIH4gVHJlYXRtZW50IHwgU2l0ZSkkY29udHJhc3RzWzJdKSlbLC1jKDE6MyldKQ0KDQojI01ldGFkYXRhDQpQQU1fSU4ucmVzJFByZWRpY3RvcjwtYygiU2l0ZSIsICJUcmVhdG1lbnQiLCAiU2l0ZSB4IFRyZWF0bWVudCIsICJDb250cm9sIFNpdGUiLCAiSGVhdGVkIFNpdGUiLCAiS0wgVHJlYXRtZW50IiwgIlNTIFRyZWF0bWVudCIpDQpQQU1fSU4ucmVzJFJlc3BvbnNlPC1yZXAoIkZ2Rm0iLCBucm93KFBBTV9JTi5yZXMpKQ0KUEFNX0lOLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChQQU0ubG1lX0lOKSRFdGEyLCByZXAoTkEsIDQpKQ0KDQpgYGANCk5vdCBub3JtYWwsIGJ1dCBtb2RlbCByZXNpZHVhbHMgYXJlIE9LLg0KDQoNCmBgYHtyIFBsb3QgRnZGbSBJbml0aWFsfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZQ0KSU5fUEFNLnN1bTwtc3VtbWFyeVNFKFRoZXJtYWxfSU4sIG1lYXN1cmV2YXI9IkZ2X0ZtIiwgZ3JvdXB2YXJzPWMoIlNpdGUiLCAiVHJlYXRtZW50IiwgIlNpdGUuVHJlYXQiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgRnZGbSBhY3Jvc3MgVHJlYXRtZW50cw0KSU5fUEFNLnBsb3Q8LWdncGxvdChJTl9QQU0uc3VtLCBhZXMoeD1TaXRlLlRyZWF0LCB5PUZ2X0ZtLCBjb2xvdXI9U2l0ZSkpICsgDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPVNpdGUuY29sb3JzLm8pKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPUZ2X0ZtLXNlLCB5bWF4PUZ2X0ZtK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fcG9pbnQoYWVzKHNoYXBlPVRyZWF0bWVudCksIHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPWMoMSwxNikpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIFRyZWF0bWVudCIsIHk9IlBob3RvY2hlbWljYWwgRWZmaWNpZW5jeSAoRnYvRm0pIiwgY29sb3VyPSJTaXRlIikrDQogIHlsaW0oMC41LCAwLjY1NSkrDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0uNiwgeT0uNjU1LCBoanVzdD0wLCBsYWJlbD0iU2l0ZSAqIiwgc2l6ZT1zaWcuc3osIGZvbnRmYWNlPSJib2xkIikrDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0uNiwgeT0uNjQ1LCBoanVzdD0wLCBsYWJlbD0iVHJlYXRtZW50ICoqKiIsIHNpemU9c2lnLnN6LCBmb250ZmFjZT0iYm9sZCIpOyBJTl9QQU0ucGxvdA0KYGBgDQoNCg0KIyMjIFJldGVudGlvbiBieSBTaXRlDQoNCiMjIyMgU3ltYmlvbnRzDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1fSU4kU3ltLnByb3ApDQpzaGFwaXJvLnRlc3QoVGhlcm1fSU4kU3ltLnByb3ApDQojTm9ybWFsDQoNCiMjTW9kZWwNCiNGdW5jdGlvbiBvZiBTaXRlLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KVG9sX1N5bS5sbWVfSU48LWxtZXIoU3ltLnByb3B+U2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9VGhlcm1fSU4pDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfU3ltLmxtZV9yZXNfSU4gPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfU3ltLmxtZV9JTiwgcGxvdCA9IEYpDQpwbG90KFRvbF9TeW0ubG1lX3Jlc19JTikNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW0ubG1lX0lOKQ0KDQpldGFfc3F1YXJlZChUb2xfU3ltLmxtZV9JTikNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TeW1fSU4ucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX1N5bS5sbWVfSU4pJGNvZWZmaWNpZW50cykNCm5hbWVzKFRvbF9TeW1fSU4ucmVzKTwtbmFtZXMoU3ltX0lOLnJlcylbMTo1XQ0KVG9sX1N5bV9JTi5yZXMkUHJlZGljdG9yPC1yZXAoIlNpdGUiLCBucm93KFRvbF9TeW1fSU4ucmVzKSkNClRvbF9TeW1fSU4ucmVzJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250IFJldGVudGlvbiIsIG5yb3coVG9sX1N5bV9JTi5yZXMpKQ0KVG9sX1N5bV9JTi5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bS5sbWVfSU4pJEV0YTIpDQoNCiMjQ29tYmluZSByZXN1bHRzDQpTeW1fSU4ucmVzPC1yYmluZChTeW1fSU4ucmVzLCBUb2xfU3ltX0lOLnJlc1syLF0pDQpgYGANCg0KDQpgYGB7ciBQbG90IFN5bWJpb250IFJldGVudGlvbiBJbml0aWFsfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZQ0KSU5fVG9sU3ltLnN1bTwtc3VtbWFyeVNFKFRoZXJtX0lOLCBtZWFzdXJldmFyPSJTeW0ucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFN5bWJpb250IFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KSU5fVG9sU3ltLnBsb3Q8LWdncGxvdChJTl9Ub2xTeW0uc3VtLCBhZXMoeD1TaXRlLCB5PVN5bS5wcm9wLCBjb2xvdXI9U2l0ZSkpICsgDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPVNpdGUuY29sb3JzLm8pKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVN5bS5wcm9wLXNlLCB5bWF4PVN5bS5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSkrDQogIGxhYnMoeD0iU2l0ZSIsIHk9IlN5bWJpb250IFJldGVudGlvbiIsIGNvbG91cj0iU2l0ZSIpKw0KICB5bGltKDAsIDEpKw0KICBhbm5vdGF0ZSgidGV4dCIsIHg9MS41LCB5PTAuNzUsIGxhYmVsPSItIiwgc2l6ZT1zaWcuc3osIGZvbnRmYWNlPSJib2xkIik7IElOX1RvbFN5bS5wbG90DQpgYGANCg0KDQojIyMjIENobG9yb3BoeWxsDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1fSU4kQ2hsLnByb3ApDQpzaGFwaXJvLnRlc3QoVGhlcm1fSU4kQ2hsLnByb3ApDQojTm9ybWFsDQoNCiMjTW9kZWwNCiNGdW5jdGlvbiBvZiBTaXRlLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KVG9sX0NobC5sbWVfSU48LWxtZXIoQ2hsLnByb3B+U2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9VGhlcm1fSU4pDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfQ2hsLmxtZV9yZXNfSU4gPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfQ2hsLmxtZV9JTiwgcGxvdCA9IEYpDQpwbG90KFRvbF9DaGwubG1lX3Jlc19JTikNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGwubG1lX0lOKQ0KDQpldGFfc3F1YXJlZChUb2xfQ2hsLmxtZV9JTikNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9DaGxfSU4ucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX0NobC5sbWVfSU4pJGNvZWZmaWNpZW50cykNCm5hbWVzKFRvbF9DaGxfSU4ucmVzKTwtbmFtZXMoQ2hsX0lOLnJlcylbMTo1XQ0KVG9sX0NobF9JTi5yZXMkUHJlZGljdG9yPC1yZXAoIlNpdGUiLCBucm93KFRvbF9DaGxfSU4ucmVzKSkNClRvbF9DaGxfSU4ucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIFJldGVudGlvbiIsIG5yb3coVG9sX0NobF9JTi5yZXMpKQ0KVG9sX0NobF9JTi5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX0NobC5sbWVfSU4pJEV0YTIpDQoNCiMjQ29tYmluZSByZXN1bHRzDQpDaGxfSU4ucmVzPC1yYmluZChDaGxfSU4ucmVzLCBUb2xfQ2hsX0lOLnJlc1syLF0pDQpgYGANCg0KDQpgYGB7ciBQbG90IENobG9yb3BoeWxsIFJldGVudGlvbiBJbml0aWFsfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpJTl9Ub2xDaGwuc3VtPC1zdW1tYXJ5U0UoVGhlcm1fSU4sIG1lYXN1cmV2YXI9IkNobC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpJTl9Ub2xDaGwucGxvdDwtZ2dwbG90KElOX1RvbENobC5zdW0sIGFlcyh4PVNpdGUsIHk9Q2hsLnByb3AsIGNvbG91cj1TaXRlKSkgKyANCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9U2l0ZS5jb2xvcnMubykrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PSJTaXRlIiwgeT0iQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIiwgY29sb3VyPSJTaXRlIikrDQogIHlsaW0oMCwgMC4zNSk7IElOX1RvbENobC5wbG90DQpgYGANCg0KDQojIyMjIEZ2Rm0NCmBgYHtyfQ0KI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUaGVybV9JTiRQQU0ucHJvcCkNCnNoYXBpcm8udGVzdChUaGVybV9JTiRQQU0ucHJvcCkNCiNOb3Qgbm9ybWFsDQoNCmhpc3QoVGhlcm1fSU4kUEFNLnByb3BeMikNCnNoYXBpcm8udGVzdChUaGVybV9JTiRQQU0ucHJvcF4yKQ0KIyNTdGlsbCBub3Qgbm9ybWFsDQoNCiMjTW9kZWwNCiNGdW5jdGlvbiBvZiBTaXRlLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KVG9sX1BBTS5sbWVfSU48LWxtZXIoUEFNLnByb3B+U2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9VGhlcm1fSU4pDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfUEFNLmxtZV9yZXNfSU4gPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfUEFNLmxtZV9JTiwgcGxvdCA9IEYpDQpwbG90KFRvbF9QQU0ubG1lX3Jlc19JTikNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9QQU0ubG1lX0lOKQ0KDQpldGFfc3F1YXJlZChUb2xfUEFNLmxtZV9JTikNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9QQU1fSU4ucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX1BBTS5sbWVfSU4pJGNvZWZmaWNpZW50cykNCm5hbWVzKFRvbF9QQU1fSU4ucmVzKTwtbmFtZXMoUEFNX0lOLnJlcylbMTo1XQ0KVG9sX1BBTV9JTi5yZXMkUHJlZGljdG9yPC1yZXAoIlNpdGUiLCBucm93KFRvbF9QQU1fSU4ucmVzKSkNClRvbF9QQU1fSU4ucmVzJFJlc3BvbnNlPC1yZXAoIkZ2Rm0gUmV0ZW50aW9uIiwgbnJvdyhUb2xfUEFNX0lOLnJlcykpDQpUb2xfUEFNX0lOLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfUEFNLmxtZV9JTikkRXRhMikNCg0KIyNDb21iaW5lIHJlc3VsdHMNClBBTV9JTi5yZXM8LXJiaW5kKFBBTV9JTi5yZXMsIFRvbF9QQU1fSU4ucmVzWzIsXSkNCmBgYA0KTm90IG5vcm1hbCwgYnV0IG1vZGVsIHJlc2lkdWFscyBhcmUgT0suDQoNCg0KYGBge3IgUGxvdCBGdkZtIFJldGVudGlvbiBJbml0aWFsfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpJTl9Ub2xQQU0uc3VtPC1zdW1tYXJ5U0UoVGhlcm1fSU4sIG1lYXN1cmV2YXI9IlBBTS5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgRnZGbSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNCklOX1RvbFBBTS5wbG90PC1nZ3Bsb3QoSU5fVG9sUEFNLnN1bSwgYWVzKHg9U2l0ZSwgeT1QQU0ucHJvcCwgY29sb3VyPVNpdGUpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1TaXRlLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1QQU0ucHJvcC1zZSwgeW1heD1QQU0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUiLCB5PSJQaG90b2NoZW1pY2FsIEVmZmljaWVuY3kgUmV0ZW50aW9uIiwgY29sb3VyPSJTaXRlIikrDQogIHlsaW0oMC42LCAxKSsNCiAgYW5ub3RhdGUoInRleHQiLCB4PTEuNSwgeT0xLCBsYWJlbD0iKiIsIHNpemU9c2lnLnN6LCBmb250ZmFjZT0iYm9sZCIpOyBJTl9Ub2xQQU0ucGxvdA0KYGBgDQoNCg0KIyBUb2xlcmFuY2UgYWZ0ZXIgVHJhbnNwbGFudA0KDQojIyMgVFAxDQpgYGB7cn0NCiMjU3Vic2V0IFRpbWVwb2ludCAxDQpUaGVybV9UUDE8LXN1YnNldChUaGVybV9ILCBUaW1lUD09IlRQMSIpDQpgYGANCg0KDQojIyMjIFN5bWJpb250cw0KYGBge3J9DQojQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRoZXJtX1RQMSRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUaGVybV9UUDEkU3ltLnByb3ApDQojTm90IG5vcm1hbA0KDQpoaXN0KGxvZyhUaGVybV9UUDEkU3ltLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRoZXJtX1RQMSRTeW0ucHJvcCsxKSkNCiMjU3RpbGwgbm90IG5vcm1hbCANCg0KIyNNb2RlbCB3aXRoIG5vIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfU3ltLmxtZV9UUDE8LWxtZXIoU3ltLnByb3B+T3JpZ2luKlNpdGUrKDF8R2Vub3R5cGUpLCBkYXRhPVRoZXJtX1RQMSkNCg0KIyNDaGVjayByZXNpZHVhbHMNClRvbF9TeW0ubG1lX3Jlc19UUDEgPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfU3ltLmxtZV9UUDEsIHBsb3QgPSBGKQ0KcGxvdChUb2xfU3ltLmxtZV9yZXNfVFAxKQ0KDQojI01vZGVsIHJlc3VsdHMNCnN1bW1hcnkoVG9sX1N5bS5sbWVfVFAxKQ0KDQpldGFfc3F1YXJlZChUb2xfU3ltLmxtZV9UUDEpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfU3ltX1RQMS5yZXM8LWRhdGEuZnJhbWUoc3VtbWFyeShUb2xfU3ltLmxtZV9UUDEpJGNvZWZmaWNpZW50c1stMSxdKQ0KVG9sX1N5bV9UUDEucmVzJFByZWRpY3RvcjwtYygiT3JpZ2luIiwgIlNpdGUiLCAiT3JpZ2luIHggU2l0ZSIpDQpUb2xfU3ltX1RQMS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bS5sbWVfVFAxKSRFdGEyKQ0KVG9sX1N5bV9UUDEucmVzJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250IFJldGVudGlvbiIsIG5yb3coVG9sX1N5bV9UUDEucmVzKSkNCg0KYGBgDQpOb3Qgbm9ybWFsLCBidXQgbW9kZWwgcmVzaWR1YWxzIGFyZSBPSy4NCg0KDQpgYGB7cn0NCiMjUGFpcndpc2UgQ29tcGFyaXNvbnMgb2YgSW50ZXJlc3QNCiNOYXRpdmUgdnMgVHJhbnNwbGFudCB3aXRoaW4gYSBTaXRlDQpUb2xfU3ltLnBhaXJfVFAxPC1lbW1lYW5zKFRvbF9TeW0ubG1lX1RQMSwgcGFpcndpc2V+T3JpZ2luIHwgU2l0ZSkNClRvbF9TeW0ucGFpcl9UUDENCg0KI0NhbGN1bGF0ZSBzdGFuZGFyZGl6ZWQgZWZmZWN0IHNpemVzIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KVG9sX1N5bS5wYWlyLmVzX1RQMTwtZGF0YS5mcmFtZShlZmZfc2l6ZShUb2xfU3ltLnBhaXJfVFAxLCBzaWdtYT1zaWdtYShUb2xfU3ltLmxtZV9UUDEpLCBlZGY9ZGYucmVzaWR1YWwoVG9sX1N5bS5sbWVfVFAxKSkpDQpUb2xfU3ltLnBhaXIuZXNfVFAxDQpUb2xfU3ltLnBhaXIuZXNfVFAxPC1Ub2xfU3ltLnBhaXIuZXNfVFAxICU+JSBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0LnNlID0gY29udHJhc3QsIFNFLmVzID0gU0UsIGRmLmVzID0gZGYpDQoNCiMjU2F2ZSBSZXN1bHRzDQpUb2xfU3ltLnBhaXJfVFAxLnJlczwtbWVyZ2UoZGF0YS5mcmFtZShUb2xfU3ltLnBhaXJfVFAxJGNvbnRyYXN0cyksIFRvbF9TeW0ucGFpci5lc19UUDFbLC1jKDEpXSkNClRvbF9TeW0ucGFpcl9UUDEucmVzJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250IFJldGVudGlvbiIsIG5yb3coVG9sX1N5bS5wYWlyX1RQMS5yZXMpKQ0KDQojI0FkZCBTaWduaWZpY2FuY2UgbGV2ZWxzDQpUb2xfU3ltLnBhaXJfVFAxLnJlcyRTaWc8LWlmZWxzZShUb2xfU3ltLnBhaXJfVFAxLnJlcyRwLnZhbHVlPDAuMDAxLCAiKioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfU3ltLnBhaXJfVFAxLnJlcyRwLnZhbHVlPDAuMDEsICIqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9TeW0ucGFpcl9UUDEucmVzJHAudmFsdWU8MC4wNSwgIioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1N5bS5wYWlyX1RQMS5yZXMkcC52YWx1ZTwwLjEsICItIiwgTkEpKSkpDQpUb2xfU3ltLnBhaXJfVFAxLnJlcw0KYGBgDQoNCg0KYGBge3IgUGxvdCBTeW1iaW9udCBSZXRlbnRpb24gVFAxfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDFfVG9sU3ltLnN1bTwtc3VtbWFyeVNFKFRoZXJtX1RQMSwgbWVhc3VyZXZhcj0iU3ltLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFN5bWJpb250IFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVFAxX1RvbFN5bS5wbG90PC1nZ3Bsb3QoVFAxX1RvbFN5bS5zdW0sIGFlcyh4PVNpdGUsIHk9U3ltLnByb3AsIGNvbG91cj1TaXRlLk9yaWcpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TeW0ucHJvcC1zZSwgeW1heD1TeW0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIE9yaWdpbiIsIHk9IlN5bWJpb250IFJldGVudGlvbiIsIGNvbG91cj0iT3JpZ2luIikrDQogIHlsaW0oMCwgMSkrDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0xLCB5PTAuNjUsIGxhYmVsPSItIiwgc2l6ZT1zaWcuc3osIGZvbnRmYWNlPSJib2xkIik7IFRQMV9Ub2xTeW0ucGxvdA0KYGBgDQoNCg0KIyMjIyBDaGxvcm9waHlsbA0KYGBge3J9DQojQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRoZXJtX1RQMSRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUaGVybV9UUDEkQ2hsLnByb3ApDQojTm90IG5vcm1hbA0KDQpoaXN0KGxvZyhUaGVybV9UUDEkQ2hsLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRoZXJtX1RQMSRDaGwucHJvcCsxKSkNCiMjU3RpbGwgbm90IG5vcm1hbCBidXQgbGVzcyBza2V3ZWQNCg0KIyNNb2RlbCB3aXRoIG5vIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfQ2hsLmxtZV9UUDE8LWxtZXIoQ2hsLnByb3B+T3JpZ2luKlNpdGUrKDF8R2Vub3R5cGUpLCBkYXRhPVRoZXJtX1RQMSkNCg0KIyNDaGVjayByZXNpZHVhbHMNClRvbF9DaGwubG1lX3Jlc19UUDEgPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfQ2hsLmxtZV9UUDEsIHBsb3QgPSBGKQ0KcGxvdChUb2xfQ2hsLmxtZV9yZXNfVFAxKQ0KDQojI01vZGVsIHJlc3VsdHMNCnN1bW1hcnkoVG9sX0NobC5sbWVfVFAxKQ0KDQpldGFfc3F1YXJlZChUb2xfQ2hsLmxtZV9UUDEpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfQ2hsX1RQMS5yZXM8LWRhdGEuZnJhbWUoc3VtbWFyeShUb2xfQ2hsLmxtZV9UUDEpJGNvZWZmaWNpZW50c1stMSxdKQ0KVG9sX0NobF9UUDEucmVzJFByZWRpY3RvcjwtYygiT3JpZ2luIiwgIlNpdGUiLCAiT3JpZ2luIHggU2l0ZSIpDQpUb2xfQ2hsX1RQMS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX0NobC5sbWVfVFAxKSRFdGEyKQ0KVG9sX0NobF9UUDEucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIFJldGVudGlvbiIsIG5yb3coVG9sX0NobF9UUDEucmVzKSkNCg0KYGBgDQpOb3Qgbm9ybWFsLCBidXQgbW9kZWwgcmVzaWR1YWxzIGFyZSBPSy4NCg0KDQpgYGB7cn0NCiMjUGFpcndpc2UgQ29tcGFyaXNvbnMgb2YgSW50ZXJlc3QNCiNOYXRpdmUgdnMgVHJhbnNwbGFudCB3aXRoaW4gYSBTaXRlDQpUb2xfQ2hsLnBhaXJfVFAxPC1lbW1lYW5zKFRvbF9DaGwubG1lX1RQMSwgcGFpcndpc2V+T3JpZ2luIHwgU2l0ZSkNClRvbF9DaGwucGFpcl9UUDENCg0KI0NhbGN1bGF0ZSBzdGFuZGFyZGl6ZWQgZWZmZWN0IHNpemVzIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KVG9sX0NobC5wYWlyLmVzX1RQMTwtZGF0YS5mcmFtZShlZmZfc2l6ZShUb2xfQ2hsLnBhaXJfVFAxLCBzaWdtYT1zaWdtYShUb2xfQ2hsLmxtZV9UUDEpLCBlZGY9ZGYucmVzaWR1YWwoVG9sX0NobC5sbWVfVFAxKSkpDQpUb2xfQ2hsLnBhaXIuZXNfVFAxDQpUb2xfQ2hsLnBhaXIuZXNfVFAxPC1Ub2xfQ2hsLnBhaXIuZXNfVFAxICU+JSBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0LnNlID0gY29udHJhc3QsIFNFLmVzID0gU0UsIGRmLmVzID0gZGYpDQoNCiMjU2F2ZSBSZXN1bHRzDQpUb2xfQ2hsLnBhaXJfVFAxLnJlczwtbWVyZ2UoZGF0YS5mcmFtZShUb2xfQ2hsLnBhaXJfVFAxJGNvbnRyYXN0cyksIFRvbF9DaGwucGFpci5lc19UUDFbLC1jKDEpXSkNClRvbF9DaGwucGFpcl9UUDEucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIFJldGVudGlvbiIsIG5yb3coVG9sX0NobC5wYWlyX1RQMS5yZXMpKQ0KDQojI0FkZCBTaWduaWZpY2FuY2UgbGV2ZWxzDQpUb2xfQ2hsLnBhaXJfVFAxLnJlcyRTaWc8LWlmZWxzZShUb2xfQ2hsLnBhaXJfVFAxLnJlcyRwLnZhbHVlPDAuMDAxLCAiKioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfQ2hsLnBhaXJfVFAxLnJlcyRwLnZhbHVlPDAuMDEsICIqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9DaGwucGFpcl9UUDEucmVzJHAudmFsdWU8MC4wNSwgIioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX0NobC5wYWlyX1RQMS5yZXMkcC52YWx1ZTwwLjEsICItIiwgTkEpKSkpDQpUb2xfQ2hsLnBhaXJfVFAxLnJlcw0KYGBgDQoNCg0KYGBge3IgUGxvdCBDaGxvcm9waHlsbCBSZXRlbnRpb24gVFAxfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDFfVG9sQ2hsLnN1bTwtc3VtbWFyeVNFKFRoZXJtX1RQMSwgbWVhc3VyZXZhcj0iQ2hsLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIENobG9yb3BoeWxsIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVFAxX1RvbENobC5wbG90PC1nZ3Bsb3QoVFAxX1RvbENobC5zdW0sIGFlcyh4PVNpdGUsIHk9Q2hsLnByb3AsIGNvbG91cj1TaXRlLk9yaWcpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIE9yaWdpbiIsIHk9IkNobG9yb3BoeWxsIFJldGVudGlvbiIsIGNvbG91cj0iT3JpZ2luIikrDQogIHlsaW0oMCwgMC4zNSk7IFRQMV9Ub2xDaGwucGxvdA0KYGBgDQoNCg0KIyMjIyBGdkZtDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1fVFAxJFBBTS5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRoZXJtX1RQMSRQQU0ucHJvcCkNCiNOb3Qgbm9ybWFsDQoNCmhpc3QoVGhlcm1fVFAxJFBBTS5wcm9wXjIpDQpzaGFwaXJvLnRlc3QoVGhlcm1fVFAxJFBBTS5wcm9wXjIpDQojI1N0aWxsIG5vdCBub3JtYWwNCg0KIyNNb2RlbCB3aXRoIG5vIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfUEFNLmxtZV9UUDE8LWxtZXIoUEFNLnByb3B+T3JpZ2luKlNpdGUrKDF8R2Vub3R5cGUpLCBkYXRhPVRoZXJtX1RQMSkNCg0KIyNDaGVjayByZXNpZHVhbHMNClRvbF9QQU0ubG1lX3Jlc19UUDEgPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfUEFNLmxtZV9UUDEsIHBsb3QgPSBGKQ0KcGxvdChUb2xfUEFNLmxtZV9yZXNfVFAxKQ0KDQojI01vZGVsIHJlc3VsdHMNCnN1bW1hcnkoVG9sX1BBTS5sbWVfVFAxKQ0KDQpldGFfc3F1YXJlZChUb2xfUEFNLmxtZV9UUDEpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfUEFNX1RQMS5yZXM8LWRhdGEuZnJhbWUoc3VtbWFyeShUb2xfUEFNLmxtZV9UUDEpJGNvZWZmaWNpZW50c1stMSxdKQ0KVG9sX1BBTV9UUDEucmVzJFByZWRpY3RvcjwtYygiT3JpZ2luIiwgIlNpdGUiLCAiT3JpZ2luIHggU2l0ZSIpDQpUb2xfUEFNX1RQMS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1BBTS5sbWVfVFAxKSRFdGEyKQ0KVG9sX1BBTV9UUDEucmVzJFJlc3BvbnNlPC1yZXAoIkZ2Rm0gUmV0ZW50aW9uIiwgbnJvdyhUb2xfUEFNX1RQMS5yZXMpKQ0KDQpgYGANCk5vdCBub3JtYWwsIGJ1dCBtb2RlbCByZXNpZHVhbHMgYXJlIE9LLg0KDQoNCmBgYHtyfQ0KIyNQYWlyd2lzZSBDb21wYXJpc29ucyBvZiBJbnRlcmVzdA0KI05hdGl2ZSB2cyBUcmFuc3BsYW50IHdpdGhpbiBhIFNpdGUNClRvbF9QQU0ucGFpcl9UUDE8LWVtbWVhbnMoVG9sX1BBTS5sbWVfVFAxLCBwYWlyd2lzZX5PcmlnaW4gfCBTaXRlKQ0KVG9sX1BBTS5wYWlyX1RQMQ0KDQojQ2FsY3VsYXRlIHN0YW5kYXJkaXplZCBlZmZlY3Qgc2l6ZXMgZm9yIHBhaXJ3aXNlIGNvbXBhcmlzb25zDQpUb2xfUEFNLnBhaXIuZXNfVFAxPC1kYXRhLmZyYW1lKGVmZl9zaXplKFRvbF9QQU0ucGFpcl9UUDEsIHNpZ21hPXNpZ21hKFRvbF9QQU0ubG1lX1RQMSksIGVkZj1kZi5yZXNpZHVhbChUb2xfUEFNLmxtZV9UUDEpKSkNClRvbF9QQU0ucGFpci5lc19UUDENClRvbF9QQU0ucGFpci5lc19UUDE8LVRvbF9QQU0ucGFpci5lc19UUDEgJT4lIGRwbHlyOjpyZW5hbWUoY29udHJhc3Quc2UgPSBjb250cmFzdCwgU0UuZXMgPSBTRSwgZGYuZXMgPSBkZikNCg0KIyNTYXZlIFJlc3VsdHMNClRvbF9QQU0ucGFpcl9UUDEucmVzPC1tZXJnZShkYXRhLmZyYW1lKFRvbF9QQU0ucGFpcl9UUDEkY29udHJhc3RzKSwgVG9sX1BBTS5wYWlyLmVzX1RQMVssLWMoMSldKQ0KVG9sX1BBTS5wYWlyX1RQMS5yZXMkUmVzcG9uc2U8LXJlcCgiRnZGbSBSZXRlbnRpb24iLCBucm93KFRvbF9QQU0ucGFpcl9UUDEucmVzKSkNCg0KIyNBZGQgU2lnbmlmaWNhbmNlIGxldmVscw0KVG9sX1BBTS5wYWlyX1RQMS5yZXMkU2lnPC1pZmVsc2UoVG9sX1BBTS5wYWlyX1RQMS5yZXMkcC52YWx1ZTwwLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1BBTS5wYWlyX1RQMS5yZXMkcC52YWx1ZTwwLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfUEFNLnBhaXJfVFAxLnJlcyRwLnZhbHVlPDAuMDUsICIqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9QQU0ucGFpcl9UUDEucmVzJHAudmFsdWU8MC4xLCAiLSIsIE5BKSkpKQ0KVG9sX1BBTS5wYWlyX1RQMS5yZXMNCmBgYA0KDQoNCmBgYHtyIFBsb3QgRnZGbSBSZXRlbnRpb24gVFAxfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDFfVG9sUEFNLnN1bTwtc3VtbWFyeVNFKFRoZXJtX1RQMSwgbWVhc3VyZXZhcj0iUEFNLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIEZ2Rm0gUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUUDFfVG9sUEFNLnBsb3Q8LWdncGxvdChUUDFfVG9sUEFNLnN1bSwgYWVzKHg9U2l0ZSwgeT1QQU0ucHJvcCwgY29sb3VyPVNpdGUuT3JpZykpICsgDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPU9yaWcuY29sb3JzLm8pKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVBBTS5wcm9wLXNlLCB5bWF4PVBBTS5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSkrDQogIGxhYnMoeD0iU2l0ZSBhbmQgT3JpZ2luIiwgeT0iUGhvdG9jaGVtaWNhbCBFZmZpY2llbmN5IFJldGVudGlvbiIsIGNvbG91cj0iT3JpZ2luIikrDQogIHlsaW0oMC42LCAxKSsNCiAgYW5ub3RhdGUoInRleHQiLCB4PTEsIHk9Ljk2LCBsYWJlbD0iKiIsIHNpemU9c2lnLnN6LCBmb250ZmFjZT0iYm9sZCIpOyBUUDFfVG9sUEFNLnBsb3QNCmBgYA0KDQoNCiMjIyMgU2F2ZSBSZXN1bHRzDQpgYGB7cn0NCiMjQ29tYmluZSBSZXN1bHRzDQpUb2xfVFAxLnJlczwtcmJpbmQoVG9sX1BBTV9UUDEucmVzLCBUb2xfU3ltX1RQMS5yZXMsIFRvbF9DaGxfVFAxLnJlcykgDQpUb2wucGFpci5yZXNfVFAxPC1yYmluZChUb2xfUEFNLnBhaXJfVFAxLnJlcywgVG9sX1N5bS5wYWlyX1RQMS5yZXMsIFRvbF9DaGwucGFpcl9UUDEucmVzKQ0KDQojI0FkZCBUaW1lcG9pbnQNClRvbF9UUDEucmVzJFRpbWVQPC1yZXAoIlRQMSIsIG5yb3coVG9sX1RQMS5yZXMpKQ0KVG9sLnBhaXIucmVzX1RQMSRUaW1lUDwtcmVwKCJUUDEiLCBucm93KFRvbC5wYWlyLnJlc19UUDEpKQ0KDQpgYGANCg0KDQojIyMgVFAyDQpgYGB7cn0NCiMjU3Vic2V0IFRpbWVwb2ludCAyDQpUaGVybV9UUDI8LXN1YnNldChUaGVybV9ILCBUaW1lUD09IlRQMiIpDQpgYGANCg0KDQojIyMjIFN5bWJpb250cw0KYGBge3J9DQojQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRoZXJtX1RQMiRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUaGVybV9UUDIkU3ltLnByb3ApDQojTm90IG5vcm1hbA0KDQpoaXN0KFRoZXJtX1RQMiRTeW0ucHJvcF4yKQ0Kc2hhcGlyby50ZXN0KFRoZXJtX1RQMiRTeW0ucHJvcF4yKQ0KIyNTdGlsbCBub3Qgbm9ybWFsDQoNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbg0KI0Z1bmN0aW9uIG9mIFNpdGUgYW5kIE9yaWdpbiwgd2l0aCBHZW5vdHlwZSBhcyBhIFJhbmRvbSBlZmZlY3QNCiNJbnRlcmFjdGlvbiBiZXR3ZWVuIFNpdGUgYW5kIE9yaWdpbg0KVG9sX1N5bS5sbWVfVFAyPC1sbWVyKFN5bS5wcm9wfk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1UaGVybV9UUDIpDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfU3ltLmxtZV9yZXNfVFAyIDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gVG9sX1N5bS5sbWVfVFAyLCBwbG90ID0gRikNCnBsb3QoVG9sX1N5bS5sbWVfcmVzX1RQMikNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW0ubG1lX1RQMikNCg0KZXRhX3NxdWFyZWQoVG9sX1N5bS5sbWVfVFAyKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9UUDIucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX1N5bS5sbWVfVFAyKSRjb2VmZmljaWVudHNbLTEsXSkNClRvbF9TeW1fVFAyLnJlcyRQcmVkaWN0b3I8LWMoIk9yaWdpbiIsICJTaXRlIiwgIk9yaWdpbiB4IFNpdGUiKQ0KVG9sX1N5bV9UUDIucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TeW0ubG1lX1RQMikkRXRhMikNClRvbF9TeW1fVFAyLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udCBSZXRlbnRpb24iLCBucm93KFRvbF9TeW1fVFAyLnJlcykpDQoNCmBgYA0KTm90IG5vcm1hbCwgYnV0IG1vZGVsIHJlc2lkdWFscyBhcmUgT0suDQoNCg0KYGBge3J9DQojI1BhaXJ3aXNlIENvbXBhcmlzb25zIG9mIEludGVyZXN0DQojTmF0aXZlIHZzIFRyYW5zcGxhbnQgd2l0aGluIGEgU2l0ZQ0KVG9sX1N5bS5wYWlyX1RQMjwtZW1tZWFucyhUb2xfU3ltLmxtZV9UUDIsIHBhaXJ3aXNlfk9yaWdpbiB8IFNpdGUpDQpUb2xfU3ltLnBhaXJfVFAyDQoNCiNDYWxjdWxhdGUgc3RhbmRhcmRpemVkIGVmZmVjdCBzaXplcyBmb3IgcGFpcndpc2UgY29tcGFyaXNvbnMNClRvbF9TeW0ucGFpci5lc19UUDI8LWRhdGEuZnJhbWUoZWZmX3NpemUoVG9sX1N5bS5wYWlyX1RQMiwgc2lnbWE9c2lnbWEoVG9sX1N5bS5sbWVfVFAyKSwgZWRmPWRmLnJlc2lkdWFsKFRvbF9TeW0ubG1lX1RQMikpKQ0KVG9sX1N5bS5wYWlyLmVzX1RQMg0KVG9sX1N5bS5wYWlyLmVzX1RQMjwtVG9sX1N5bS5wYWlyLmVzX1RQMiAlPiUgZHBseXI6OnJlbmFtZShjb250cmFzdC5zZSA9IGNvbnRyYXN0LCBTRS5lcyA9IFNFLCBkZi5lcyA9IGRmKQ0KDQojI1NhdmUgUmVzdWx0cw0KVG9sX1N5bS5wYWlyX1RQMi5yZXM8LW1lcmdlKGRhdGEuZnJhbWUoVG9sX1N5bS5wYWlyX1RQMiRjb250cmFzdHMpLCBUb2xfU3ltLnBhaXIuZXNfVFAyWywtYygxKV0pDQpUb2xfU3ltLnBhaXJfVFAyLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udCBSZXRlbnRpb24iLCBucm93KFRvbF9TeW0ucGFpcl9UUDIucmVzKSkNCg0KIyNBZGQgU2lnbmlmaWNhbmNlIGxldmVscw0KVG9sX1N5bS5wYWlyX1RQMi5yZXMkU2lnPC1pZmVsc2UoVG9sX1N5bS5wYWlyX1RQMi5yZXMkcC52YWx1ZTwwLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1N5bS5wYWlyX1RQMi5yZXMkcC52YWx1ZTwwLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfU3ltLnBhaXJfVFAyLnJlcyRwLnZhbHVlPDAuMDUsICIqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9TeW0ucGFpcl9UUDIucmVzJHAudmFsdWU8MC4xLCAiLSIsIE5BKSkpKQ0KVG9sX1N5bS5wYWlyX1RQMi5yZXMNCmBgYA0KDQoNCmBgYHtyIFBsb3QgU3ltYmlvbnQgUmV0ZW50aW9uIFRQMn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIE9yaWdpbg0KVFAyX1RvbFN5bS5zdW08LXN1bW1hcnlTRShUaGVybV9UUDIsIG1lYXN1cmV2YXI9IlN5bS5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUiLCAiT3JpZ2luIiwgIlNpdGUuT3JpZyIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRQMl9Ub2xTeW0ucGxvdDwtZ2dwbG90KFRQMl9Ub2xTeW0uc3VtLCBhZXMoeD1TaXRlLCB5PVN5bS5wcm9wLCBjb2xvdXI9U2l0ZS5PcmlnKSkgKyANCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9T3JpZy5jb2xvcnMubykrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U3ltLnByb3Atc2UsIHltYXg9U3ltLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PSJTaXRlIGFuZCBPcmlnaW4iLCB5PSJTeW1iaW9udCBSZXRlbnRpb24iLCBjb2xvdXI9Ik9yaWdpbiIpKw0KICB5bGltKDAsIDEpKw0KIGdlb21fYnJhY2tldCh4bWluPTEsIHhtYXg9MiwgeS5wb3NpdGlvbj0uMDQsIGxhYmVsLnNpemU9bGV2ZWxzLnN6LCBsYWJlbD0iKiIsIGluaGVyaXQuYWVzID0gRkFMU0UpOyBUUDJfVG9sU3ltLnBsb3QNCmBgYA0KDQoNCiMjIyMgQ2hsb3JvcGh5bGwNCmBgYHtyfQ0KI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUaGVybV9UUDIkQ2hsLnByb3ApDQpzaGFwaXJvLnRlc3QoVGhlcm1fVFAyJENobC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfQ2hsLmxtZV9UUDI8LWxtZXIoQ2hsLnByb3B+T3JpZ2luKlNpdGUrKDF8R2Vub3R5cGUpLCBkYXRhPVRoZXJtX1RQMikNCg0KIyNDaGVjayByZXNpZHVhbHMNClRvbF9DaGwubG1lX3Jlc19UUDIgPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfQ2hsLmxtZV9UUDIsIHBsb3QgPSBGKQ0KcGxvdChUb2xfQ2hsLmxtZV9yZXNfVFAyKQ0KDQojI01vZGVsIHJlc3VsdHMNCnN1bW1hcnkoVG9sX0NobC5sbWVfVFAyKQ0KDQpldGFfc3F1YXJlZChUb2xfQ2hsLmxtZV9UUDIpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfQ2hsX1RQMi5yZXM8LWRhdGEuZnJhbWUoc3VtbWFyeShUb2xfQ2hsLmxtZV9UUDIpJGNvZWZmaWNpZW50c1stMSxdKQ0KVG9sX0NobF9UUDIucmVzJFByZWRpY3RvcjwtYygiT3JpZ2luIiwgIlNpdGUiLCAiT3JpZ2luIHggU2l0ZSIpDQpUb2xfQ2hsX1RQMi5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX0NobC5sbWVfVFAyKSRFdGEyKQ0KVG9sX0NobF9UUDIucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIFJldGVudGlvbiIsIG5yb3coVG9sX0NobF9UUDIucmVzKSkNCg0KYGBgDQoNCg0KYGBge3J9DQojI1BhaXJ3aXNlIENvbXBhcmlzb25zIG9mIEludGVyZXN0DQojTmF0aXZlIHZzIFRyYW5zcGxhbnQgd2l0aGluIGEgU2l0ZQ0KVG9sX0NobC5wYWlyX1RQMjwtZW1tZWFucyhUb2xfQ2hsLmxtZV9UUDIsIHBhaXJ3aXNlfk9yaWdpbiB8IFNpdGUpDQpUb2xfQ2hsLnBhaXJfVFAyDQoNCiNDYWxjdWxhdGUgc3RhbmRhcmRpemVkIGVmZmVjdCBzaXplcyBmb3IgcGFpcndpc2UgY29tcGFyaXNvbnMNClRvbF9DaGwucGFpci5lc19UUDI8LWRhdGEuZnJhbWUoZWZmX3NpemUoVG9sX0NobC5wYWlyX1RQMiwgc2lnbWE9c2lnbWEoVG9sX0NobC5sbWVfVFAyKSwgZWRmPWRmLnJlc2lkdWFsKFRvbF9DaGwubG1lX1RQMikpKQ0KVG9sX0NobC5wYWlyLmVzX1RQMg0KVG9sX0NobC5wYWlyLmVzX1RQMjwtVG9sX0NobC5wYWlyLmVzX1RQMiAlPiUgZHBseXI6OnJlbmFtZShjb250cmFzdC5zZSA9IGNvbnRyYXN0LCBTRS5lcyA9IFNFLCBkZi5lcyA9IGRmKQ0KDQojI1NhdmUgUmVzdWx0cw0KVG9sX0NobC5wYWlyX1RQMi5yZXM8LW1lcmdlKGRhdGEuZnJhbWUoVG9sX0NobC5wYWlyX1RQMiRjb250cmFzdHMpLCBUb2xfQ2hsLnBhaXIuZXNfVFAyWywtYygxKV0pDQpUb2xfQ2hsLnBhaXJfVFAyLnJlcyRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCBSZXRlbnRpb24iLCBucm93KFRvbF9DaGwucGFpcl9UUDIucmVzKSkNCg0KIyNBZGQgU2lnbmlmaWNhbmNlIGxldmVscw0KVG9sX0NobC5wYWlyX1RQMi5yZXMkU2lnPC1pZmVsc2UoVG9sX0NobC5wYWlyX1RQMi5yZXMkcC52YWx1ZTwwLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX0NobC5wYWlyX1RQMi5yZXMkcC52YWx1ZTwwLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfQ2hsLnBhaXJfVFAyLnJlcyRwLnZhbHVlPDAuMDUsICIqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9DaGwucGFpcl9UUDIucmVzJHAudmFsdWU8MC4xLCAiLSIsIE5BKSkpKQ0KVG9sX0NobC5wYWlyX1RQMi5yZXMNCmBgYA0KDQoNCmBgYHtyIFBsb3QgQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIFRQMn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIE9yaWdpbg0KVFAyX1RvbENobC5zdW08LXN1bW1hcnlTRShUaGVybV9UUDIsIG1lYXN1cmV2YXI9IkNobC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUiLCAiT3JpZ2luIiwgIlNpdGUuT3JpZyIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRQMl9Ub2xDaGwucGxvdDwtZ2dwbG90KFRQMl9Ub2xDaGwuc3VtLCBhZXMoeD1TaXRlLCB5PUNobC5wcm9wLCBjb2xvdXI9U2l0ZS5PcmlnKSkgKyANCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9T3JpZy5jb2xvcnMubykrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PSJTaXRlIGFuZCBPcmlnaW4iLCB5PSJDaGxvcm9waHlsbCBSZXRlbnRpb24iLCBjb2xvdXI9Ik9yaWdpbiIpKw0KICB5bGltKDAsIDAuMzUpKw0KICBnZW9tX2JyYWNrZXQoeG1pbj0xLCB4bWF4PTIsIHkucG9zaXRpb249LjAyLCBsYWJlbC5zaXplPWxldmVscy5zeiwgbGFiZWw9Ii0iLCBpbmhlcml0LmFlcyA9IEZBTFNFKTsgVFAyX1RvbENobC5wbG90DQpgYGANCg0KDQojIyMjIEZ2Rm0NCmBgYHtyfQ0KI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUaGVybV9UUDIkUEFNLnByb3ApDQpzaGFwaXJvLnRlc3QoVGhlcm1fVFAyJFBBTS5wcm9wKQ0KI05vdCBub3JtYWwNCg0KaGlzdChUaGVybV9UUDIkUEFNLnByb3BeMikNCnNoYXBpcm8udGVzdChUaGVybV9UUDIkUEFNLnByb3BeMikNCiMjU3RpbGwgbm90IG5vcm1hbA0KDQojI01vZGVsDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfUEFNLmxtZV9UUDI8LWxtZXIoUEFNLnByb3B+T3JpZ2luKlNpdGUrKDF8R2Vub3R5cGUpLCBkYXRhPVRoZXJtX1RQMikNCg0KIyNDaGVjayByZXNpZHVhbHMNClRvbF9QQU0ubG1lX3Jlc19UUDIgPC0gc2ltdWxhdGVSZXNpZHVhbHMoZml0dGVkTW9kZWwgPSBUb2xfUEFNLmxtZV9UUDIsIHBsb3QgPSBGKQ0KcGxvdChUb2xfUEFNLmxtZV9yZXNfVFAyKQ0KDQojI01vZGVsIHJlc3VsdHMNCnN1bW1hcnkoVG9sX1BBTS5sbWVfVFAyKQ0KDQpldGFfc3F1YXJlZChUb2xfUEFNLmxtZV9UUDIpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfUEFNX1RQMi5yZXM8LWRhdGEuZnJhbWUoc3VtbWFyeShUb2xfUEFNLmxtZV9UUDIpJGNvZWZmaWNpZW50c1stMSxdKQ0KVG9sX1BBTV9UUDIucmVzJFByZWRpY3RvcjwtYygiT3JpZ2luIiwgIlNpdGUiLCAiT3JpZ2luIHggU2l0ZSIpDQpUb2xfUEFNX1RQMi5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1BBTS5sbWVfVFAyKSRFdGEyKQ0KVG9sX1BBTV9UUDIucmVzJFJlc3BvbnNlPC1yZXAoIkZ2Rm0gUmV0ZW50aW9uIiwgbnJvdyhUb2xfUEFNX1RQMi5yZXMpKQ0KDQpgYGANCk5vdCBub3JtYWwsIGJ1dCBtb2RlbCByZXNpZHVhbHMgYXJlIE9LLg0KDQoNCmBgYHtyfQ0KIyNQYWlyd2lzZSBDb21wYXJpc29ucyBvZiBJbnRlcmVzdA0KI05hdGl2ZSB2cyBUcmFuc3BsYW50IHdpdGhpbiBhIFNpdGUNClRvbF9QQU0ucGFpcl9UUDI8LWVtbWVhbnMoVG9sX1BBTS5sbWVfVFAyLCBwYWlyd2lzZX5PcmlnaW4gfCBTaXRlKQ0KVG9sX1BBTS5wYWlyX1RQMg0KDQojQ2FsY3VsYXRlIHN0YW5kYXJkaXplZCBlZmZlY3Qgc2l6ZXMgZm9yIHBhaXJ3aXNlIGNvbXBhcmlzb25zDQpUb2xfUEFNLnBhaXIuZXNfVFAyPC1kYXRhLmZyYW1lKGVmZl9zaXplKFRvbF9QQU0ucGFpcl9UUDIsIHNpZ21hPXNpZ21hKFRvbF9QQU0ubG1lX1RQMiksIGVkZj1kZi5yZXNpZHVhbChUb2xfUEFNLmxtZV9UUDIpKSkNClRvbF9QQU0ucGFpci5lc19UUDINClRvbF9QQU0ucGFpci5lc19UUDI8LVRvbF9QQU0ucGFpci5lc19UUDIgJT4lIGRwbHlyOjpyZW5hbWUoY29udHJhc3Quc2UgPSBjb250cmFzdCwgU0UuZXMgPSBTRSwgZGYuZXMgPSBkZikNCg0KIyNTYXZlIFJlc3VsdHMNClRvbF9QQU0ucGFpcl9UUDIucmVzPC1tZXJnZShkYXRhLmZyYW1lKFRvbF9QQU0ucGFpcl9UUDIkY29udHJhc3RzKSwgVG9sX1BBTS5wYWlyLmVzX1RQMlssLWMoMSldKQ0KVG9sX1BBTS5wYWlyX1RQMi5yZXMkUmVzcG9uc2U8LXJlcCgiRnZGbSBSZXRlbnRpb24iLCBucm93KFRvbF9QQU0ucGFpcl9UUDIucmVzKSkNCg0KIyNBZGQgU2lnbmlmaWNhbmNlIGxldmVscw0KVG9sX1BBTS5wYWlyX1RQMi5yZXMkU2lnPC1pZmVsc2UoVG9sX1BBTS5wYWlyX1RQMi5yZXMkcC52YWx1ZTwwLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1BBTS5wYWlyX1RQMi5yZXMkcC52YWx1ZTwwLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfUEFNLnBhaXJfVFAyLnJlcyRwLnZhbHVlPDAuMDUsICIqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9QQU0ucGFpcl9UUDIucmVzJHAudmFsdWU8MC4xLCAiLSIsIE5BKSkpKQ0KVG9sX1BBTS5wYWlyX1RQMi5yZXMNCmBgYA0KDQoNCmBgYHtyIFBsb3QgRnZGbSBSZXRlbnRpb24gVFAyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDJfVG9sUEFNLnN1bTwtc3VtbWFyeVNFKFRoZXJtX1RQMiwgbWVhc3VyZXZhcj0iUEFNLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVFAyX1RvbFBBTS5wbG90PC1nZ3Bsb3QoVFAyX1RvbFBBTS5zdW0sIGFlcyh4PVNpdGUsIHk9UEFNLnByb3AsIGNvbG91cj1TaXRlLk9yaWcpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1QQU0ucHJvcC1zZSwgeW1heD1QQU0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIE9yaWdpbiIsIHk9IlBob3RvY2hlbWljYWwgRWZmaWNpZW5jeSBSZXRlbnRpb24iLCBjb2xvdXI9Ik9yaWdpbiIpKw0KICB5bGltKDAuNiwgMSkrDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0xLCB5PTAuOTYsIGxhYmVsPSIqKiIsIHNpemU9c2lnLnN6LCBmb250ZmFjZT0iYm9sZCIpKw0KIGdlb21fYnJhY2tldCh4bWluPTEsIHhtYXg9MiwgeS5wb3NpdGlvbj0uNjEyLCBsYWJlbC5zaXplPWxldmVscy5zeiwgbGFiZWw9IioiLCBpbmhlcml0LmFlcyA9IEZBTFNFKTsgVFAyX1RvbFBBTS5wbG90DQpgYGANCg0KDQojIyMjIFNhdmUgUmVzdWx0cw0KYGBge3J9DQojI0NvbWJpbmUgUmVzdWx0cw0KVG9sX1RQMi5yZXM8LXJiaW5kKFRvbF9QQU1fVFAyLnJlcywgVG9sX1N5bV9UUDIucmVzLCBUb2xfQ2hsX1RQMi5yZXMpDQpUb2wucGFpci5yZXNfVFAyPC1yYmluZChUb2xfUEFNLnBhaXJfVFAyLnJlcywgVG9sX1N5bS5wYWlyX1RQMi5yZXMsIFRvbF9DaGwucGFpcl9UUDIucmVzKQ0KDQojI0FkZCBUaW1lcG9pbnQNClRvbF9UUDIucmVzJFRpbWVQPC1yZXAoIlRQMiIsIG5yb3coVG9sX1RQMi5yZXMpKQ0KVG9sLnBhaXIucmVzX1RQMiRUaW1lUDwtcmVwKCJUUDIiLCBucm93KFRvbC5wYWlyLnJlc19UUDIpKQ0KDQpgYGANCg0KDQojIyMgVFAzDQpgYGB7cn0NCiMjU3Vic2V0IFRpbWVwb2ludCAzDQpUaGVybV9UUDM8LXN1YnNldChUaGVybV9ILCBUaW1lUD09IlRQMyIpDQpgYGANCg0KDQojIyMjIFN5bWJpb250cw0KYGBge3J9DQojQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRoZXJtX1RQMyRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUaGVybV9UUDMkU3ltLnByb3ApDQojTm90IG5vcm1hbA0KDQpoaXN0KFRoZXJtX1RQMyRTeW0ucHJvcF4yKQ0Kc2hhcGlyby50ZXN0KFRoZXJtX1RQMyRTeW0ucHJvcF4yKQ0KIyNTdGlsbCBub3Qgbm9ybWFsIGJ1dCBsZXNzIHNrZXdlZA0KDQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24NCiNGdW5jdGlvbiBvZiBTaXRlIGFuZCBPcmlnaW4sIHdpdGggR2Vub3R5cGUgYXMgYSBSYW5kb20gZWZmZWN0DQojSW50ZXJhY3Rpb24gYmV0d2VlbiBTaXRlIGFuZCBPcmlnaW4NClRvbF9TeW0ubG1lX1RQMzwtbG1lcihTeW0ucHJvcH5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9VGhlcm1fVFAzKQ0KDQojI0NoZWNrIHJlc2lkdWFscw0KVG9sX1N5bS5sbWVfcmVzX1RQMyA8LSBzaW11bGF0ZVJlc2lkdWFscyhmaXR0ZWRNb2RlbCA9IFRvbF9TeW0ubG1lX1RQMywgcGxvdCA9IEYpDQpwbG90KFRvbF9TeW0ubG1lX3Jlc19UUDMpDQoNCiMjTW9kZWwgcmVzdWx0cw0Kc3VtbWFyeShUb2xfU3ltLmxtZV9UUDMpDQoNCmV0YV9zcXVhcmVkKFRvbF9TeW0ubG1lX1RQMykNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TeW1fVFAzLnJlczwtZGF0YS5mcmFtZShzdW1tYXJ5KFRvbF9TeW0ubG1lX1RQMykkY29lZmZpY2llbnRzWy0xLF0pDQpUb2xfU3ltX1RQMy5yZXMkUHJlZGljdG9yPC1jKCJPcmlnaW4iLCAiU2l0ZSIsICJPcmlnaW4geCBTaXRlIikNClRvbF9TeW1fVFAzLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU3ltLmxtZV9UUDMpJEV0YTIpDQpUb2xfU3ltX1RQMy5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnQgUmV0ZW50aW9uIiwgbnJvdyhUb2xfU3ltX1RQMy5yZXMpKQ0KDQpgYGANCk5vdCBub3JtYWwsIGJ1dCBtb2RlbCByZXNpZHVhbHMgYXJlIE9LLg0KDQoNCmBgYHtyfQ0KIyNQYWlyd2lzZSBDb21wYXJpc29ucyBvZiBJbnRlcmVzdA0KI05hdGl2ZSB2cyBUcmFuc3BsYW50IHdpdGhpbiBhIFNpdGUNClRvbF9TeW0ucGFpcl9UUDM8LWVtbWVhbnMoVG9sX1N5bS5sbWVfVFAzLCBwYWlyd2lzZX5PcmlnaW4gfCBTaXRlKQ0KVG9sX1N5bS5wYWlyX1RQMw0KDQojQ2FsY3VsYXRlIHN0YW5kYXJkaXplZCBlZmZlY3Qgc2l6ZXMgZm9yIHBhaXJ3aXNlIGNvbXBhcmlzb25zDQpUb2xfU3ltLnBhaXIuZXNfVFAzPC1kYXRhLmZyYW1lKGVmZl9zaXplKFRvbF9TeW0ucGFpcl9UUDMsIHNpZ21hPXNpZ21hKFRvbF9TeW0ubG1lX1RQMyksIGVkZj1kZi5yZXNpZHVhbChUb2xfU3ltLmxtZV9UUDMpKSkNClRvbF9TeW0ucGFpci5lc19UUDMNClRvbF9TeW0ucGFpci5lc19UUDM8LVRvbF9TeW0ucGFpci5lc19UUDMgJT4lIGRwbHlyOjpyZW5hbWUoY29udHJhc3Quc2UgPSBjb250cmFzdCwgU0UuZXMgPSBTRSwgZGYuZXMgPSBkZikNCg0KIyNTYXZlIFJlc3VsdHMNClRvbF9TeW0ucGFpcl9UUDMucmVzPC1tZXJnZShkYXRhLmZyYW1lKFRvbF9TeW0ucGFpcl9UUDMkY29udHJhc3RzKSwgVG9sX1N5bS5wYWlyLmVzX1RQM1ssLWMoMSldKQ0KVG9sX1N5bS5wYWlyX1RQMy5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnQgUmV0ZW50aW9uIiwgbnJvdyhUb2xfU3ltLnBhaXJfVFAzLnJlcykpDQoNCiMjQWRkIFNpZ25pZmljYW5jZSBsZXZlbHMNClRvbF9TeW0ucGFpcl9UUDMucmVzJFNpZzwtaWZlbHNlKFRvbF9TeW0ucGFpcl9UUDMucmVzJHAudmFsdWU8MC4wMDEsICIqKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9TeW0ucGFpcl9UUDMucmVzJHAudmFsdWU8MC4wMSwgIioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1N5bS5wYWlyX1RQMy5yZXMkcC52YWx1ZTwwLjA1LCAiKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfU3ltLnBhaXJfVFAzLnJlcyRwLnZhbHVlPDAuMSwgIi0iLCBOQSkpKSkNClRvbF9TeW0ucGFpcl9UUDMucmVzDQpgYGANCg0KDQpgYGB7ciBQbG90IFN5bWJpb250IFJldGVudGlvbiBUUDN9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBPcmlnaW4NClRQM19Ub2xTeW0uc3VtPC1zdW1tYXJ5U0UoVGhlcm1fVFAzLCBtZWFzdXJldmFyPSJTeW0ucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlIiwgIk9yaWdpbiIsICJTaXRlLk9yaWciKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUUDNfVG9sU3ltLnBsb3Q8LWdncGxvdChUUDNfVG9sU3ltLnN1bSwgYWVzKHg9U2l0ZSwgeT1TeW0ucHJvcCwgY29sb3VyPVNpdGUuT3JpZykpICsgDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPU9yaWcuY29sb3JzLm8pKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVN5bS5wcm9wLXNlLCB5bWF4PVN5bS5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSkrDQogIGxhYnMoeD0iU2l0ZSBhbmQgT3JpZ2luIiwgeT0iU3ltYmlvbnQgUmV0ZW50aW9uIiwgY29sb3VyPSJPcmlnaW4iKSsNCiAgeWxpbSgwLCAxKSsNCiBnZW9tX2JyYWNrZXQoeG1pbj0xLCB4bWF4PTIsIHkucG9zaXRpb249LjA0LCBsYWJlbC5zaXplPWxldmVscy5zeiwgbGFiZWw9IioiLCBpbmhlcml0LmFlcyA9IEZBTFNFKTsgVFAzX1RvbFN5bS5wbG90DQpgYGANCg0KDQojIyMjIENobG9yb3BoeWxsDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1fVFAzJENobC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRoZXJtX1RQMyRDaGwucHJvcCkNCiNOb3Qgbm9ybWFsDQoNCmhpc3QobG9nKFRoZXJtX1RQMyRDaGwucHJvcCsxKSkNCnNoYXBpcm8udGVzdChsb2coVGhlcm1fVFAzJENobC5wcm9wKzEpKQ0KIyNTdGlsbCBub3Qgbm9ybWFsIGJ1dCBsZXNzIHNrZXdlZA0KDQojI01vZGVsIHdpdGggbG9nICsxIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfQ2hsLmxtZV9UUDM8LWxtZXIobG9nKENobC5wcm9wKzEpfk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1UaGVybV9UUDMpDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfQ2hsLmxtZV9yZXNfVFAzIDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gVG9sX0NobC5sbWVfVFAzLCBwbG90ID0gRikNCnBsb3QoVG9sX0NobC5sbWVfcmVzX1RQMykNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGwubG1lX1RQMykNCg0KZXRhX3NxdWFyZWQoVG9sX0NobC5sbWVfVFAzKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX0NobF9UUDMucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX0NobC5sbWVfVFAzKSRjb2VmZmljaWVudHNbLTEsXSkNClRvbF9DaGxfVFAzLnJlcyRQcmVkaWN0b3I8LWMoIk9yaWdpbiIsICJTaXRlIiwgIk9yaWdpbiB4IFNpdGUiKQ0KVG9sX0NobF9UUDMucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGwubG1lX1RQMykkRXRhMikNClRvbF9DaGxfVFAzLnJlcyRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCBSZXRlbnRpb24iLCBucm93KFRvbF9DaGxfVFAzLnJlcykpDQoNCmBgYA0KTm90IG5vcm1hbCwgYnV0IG1vZGVsIHJlc2lkdWFscyBhcmUgT0suDQoNCg0KYGBge3J9DQojI1BhaXJ3aXNlIENvbXBhcmlzb25zIG9mIEludGVyZXN0DQojTmF0aXZlIHZzIFRyYW5zcGxhbnQgd2l0aGluIGEgU2l0ZQ0KVG9sX0NobC5wYWlyX1RQMzwtZW1tZWFucyhUb2xfQ2hsLmxtZV9UUDMsIHBhaXJ3aXNlfk9yaWdpbiB8IFNpdGUpDQpUb2xfQ2hsLnBhaXJfVFAzDQoNCiNDYWxjdWxhdGUgc3RhbmRhcmRpemVkIGVmZmVjdCBzaXplcyBmb3IgcGFpcndpc2UgY29tcGFyaXNvbnMNClRvbF9DaGwucGFpci5lc19UUDM8LWRhdGEuZnJhbWUoZWZmX3NpemUoVG9sX0NobC5wYWlyX1RQMywgc2lnbWE9c2lnbWEoVG9sX0NobC5sbWVfVFAzKSwgZWRmPWRmLnJlc2lkdWFsKFRvbF9DaGwubG1lX1RQMykpKQ0KVG9sX0NobC5wYWlyLmVzX1RQMw0KVG9sX0NobC5wYWlyLmVzX1RQMzwtVG9sX0NobC5wYWlyLmVzX1RQMyAlPiUgZHBseXI6OnJlbmFtZShjb250cmFzdC5zZSA9IGNvbnRyYXN0LCBTRS5lcyA9IFNFLCBkZi5lcyA9IGRmKQ0KDQojI1NhdmUgUmVzdWx0cw0KVG9sX0NobC5wYWlyX1RQMy5yZXM8LW1lcmdlKGRhdGEuZnJhbWUoVG9sX0NobC5wYWlyX1RQMyRjb250cmFzdHMpLCBUb2xfQ2hsLnBhaXIuZXNfVFAzWywtYygxKV0pDQpUb2xfQ2hsLnBhaXJfVFAzLnJlcyRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCBSZXRlbnRpb24iLCBucm93KFRvbF9DaGwucGFpcl9UUDMucmVzKSkNCg0KIyNBZGQgU2lnbmlmaWNhbmNlIGxldmVscw0KVG9sX0NobC5wYWlyX1RQMy5yZXMkU2lnPC1pZmVsc2UoVG9sX0NobC5wYWlyX1RQMy5yZXMkcC52YWx1ZTwwLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX0NobC5wYWlyX1RQMy5yZXMkcC52YWx1ZTwwLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfQ2hsLnBhaXJfVFAzLnJlcyRwLnZhbHVlPDAuMDUsICIqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9DaGwucGFpcl9UUDMucmVzJHAudmFsdWU8MC4xLCAiLSIsIE5BKSkpKQ0KVG9sX0NobC5wYWlyX1RQMy5yZXMNCmBgYA0KDQoNCmBgYHtyIFBsb3QgQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIFRQM30NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIE9yaWdpbg0KVFAzX1RvbENobC5zdW08LXN1bW1hcnlTRShUaGVybV9UUDMsIG1lYXN1cmV2YXI9IkNobC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUiLCAiT3JpZ2luIiwgIlNpdGUuT3JpZyIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRQM19Ub2xDaGwucGxvdDwtZ2dwbG90KFRQM19Ub2xDaGwuc3VtLCBhZXMoeD1TaXRlLCB5PUNobC5wcm9wLCBjb2xvdXI9U2l0ZS5PcmlnKSkgKyANCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9T3JpZy5jb2xvcnMubykrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PSJTaXRlIGFuZCBPcmlnaW4iLCB5PSJDaGxvcm9waHlsbCBSZXRlbnRpb24iLCBjb2xvdXI9Ik9yaWdpbiIpKw0KICB5bGltKDAsIDEpOyBUUDNfVG9sQ2hsLnBsb3QNCmBgYA0KDQoNCiMjIyMgRnZGbQ0KYGBge3J9DQojQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRoZXJtX1RQMyRQQU0ucHJvcCkNCnNoYXBpcm8udGVzdChUaGVybV9UUDMkUEFNLnByb3ApDQojTm9ybWFsDQoNCiMjTW9kZWwNCiNGdW5jdGlvbiBvZiBTaXRlIGFuZCBPcmlnaW4sIHdpdGggR2Vub3R5cGUgYXMgYSBSYW5kb20gZWZmZWN0DQojSW50ZXJhY3Rpb24gYmV0d2VlbiBTaXRlIGFuZCBPcmlnaW4NClRvbF9QQU0ubG1lX1RQMzwtbG1lcihQQU0ucHJvcH5PcmlnaW4qU2l0ZSsoMXxHZW5vdHlwZSksIGRhdGE9VGhlcm1fVFAzKQ0KDQojI0NoZWNrIHJlc2lkdWFscw0KVG9sX1BBTS5sbWVfcmVzX1RQMyA8LSBzaW11bGF0ZVJlc2lkdWFscyhmaXR0ZWRNb2RlbCA9IFRvbF9QQU0ubG1lX1RQMywgcGxvdCA9IEYpDQpwbG90KFRvbF9QQU0ubG1lX3Jlc19UUDMpDQoNCiMjTW9kZWwgcmVzdWx0cw0Kc3VtbWFyeShUb2xfUEFNLmxtZV9UUDMpDQoNCmV0YV9zcXVhcmVkKFRvbF9QQU0ubG1lX1RQMykNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9QQU1fVFAzLnJlczwtZGF0YS5mcmFtZShzdW1tYXJ5KFRvbF9QQU0ubG1lX1RQMykkY29lZmZpY2llbnRzWy0xLF0pDQpUb2xfUEFNX1RQMy5yZXMkUHJlZGljdG9yPC1jKCJPcmlnaW4iLCAiU2l0ZSIsICJPcmlnaW4geCBTaXRlIikNClRvbF9QQU1fVFAzLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfUEFNLmxtZV9UUDMpJEV0YTIpDQpUb2xfUEFNX1RQMy5yZXMkUmVzcG9uc2U8LXJlcCgiRnZGbSBSZXRlbnRpb24iLCBucm93KFRvbF9QQU1fVFAzLnJlcykpDQoNCmBgYA0KDQpgYGB7cn0NCiMjUGFpcndpc2UgQ29tcGFyaXNvbnMgb2YgSW50ZXJlc3QNCiNOYXRpdmUgdnMgVHJhbnNwbGFudCB3aXRoaW4gYSBTaXRlDQpUb2xfUEFNLnBhaXJfVFAzPC1lbW1lYW5zKFRvbF9QQU0ubG1lX1RQMywgcGFpcndpc2V+T3JpZ2luIHwgU2l0ZSkNClRvbF9QQU0ucGFpcl9UUDMNCg0KI0NhbGN1bGF0ZSBzdGFuZGFyZGl6ZWQgZWZmZWN0IHNpemVzIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KVG9sX1BBTS5wYWlyLmVzX1RQMzwtZGF0YS5mcmFtZShlZmZfc2l6ZShUb2xfUEFNLnBhaXJfVFAzLCBzaWdtYT1zaWdtYShUb2xfUEFNLmxtZV9UUDMpLCBlZGY9ZGYucmVzaWR1YWwoVG9sX1BBTS5sbWVfVFAzKSkpDQpUb2xfUEFNLnBhaXIuZXNfVFAzDQpUb2xfUEFNLnBhaXIuZXNfVFAzPC1Ub2xfUEFNLnBhaXIuZXNfVFAzICU+JSBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0LnNlID0gY29udHJhc3QsIFNFLmVzID0gU0UsIGRmLmVzID0gZGYpDQoNCiMjU2F2ZSBSZXN1bHRzDQpUb2xfUEFNLnBhaXJfVFAzLnJlczwtbWVyZ2UoZGF0YS5mcmFtZShUb2xfUEFNLnBhaXJfVFAzJGNvbnRyYXN0cyksIFRvbF9QQU0ucGFpci5lc19UUDNbLC1jKDEpXSkNClRvbF9QQU0ucGFpcl9UUDMucmVzJFJlc3BvbnNlPC1yZXAoIkZ2Rm0gUmV0ZW50aW9uIiwgbnJvdyhUb2xfUEFNLnBhaXJfVFAzLnJlcykpDQoNCiMjQWRkIFNpZ25pZmljYW5jZSBsZXZlbHMNClRvbF9QQU0ucGFpcl9UUDMucmVzJFNpZzwtaWZlbHNlKFRvbF9QQU0ucGFpcl9UUDMucmVzJHAudmFsdWU8MC4wMDEsICIqKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9QQU0ucGFpcl9UUDMucmVzJHAudmFsdWU8MC4wMSwgIioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1BBTS5wYWlyX1RQMy5yZXMkcC52YWx1ZTwwLjA1LCAiKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfUEFNLnBhaXJfVFAzLnJlcyRwLnZhbHVlPDAuMSwgIi0iLCBOQSkpKSkNClRvbF9QQU0ucGFpcl9UUDMucmVzDQpgYGANCg0KDQpgYGB7ciBQbG90IEZ2Rm0gUmV0ZW50aW9uIFRQM30NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIE9yaWdpbg0KVFAzX1RvbFBBTS5zdW08LXN1bW1hcnlTRShUaGVybV9UUDMsIG1lYXN1cmV2YXI9IlBBTS5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUiLCAiT3JpZ2luIiwgIlNpdGUuT3JpZyIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRQM19Ub2xQQU0ucGxvdDwtZ2dwbG90KFRQM19Ub2xQQU0uc3VtLCBhZXMoeD1TaXRlLCB5PVBBTS5wcm9wLCBjb2xvdXI9U2l0ZS5PcmlnKSkgKyANCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9T3JpZy5jb2xvcnMubykrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49UEFNLnByb3Atc2UsIHltYXg9UEFNLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PSJTaXRlIGFuZCBPcmlnaW4iLCB5PSJQaG90b2NoZW1pY2FsIEVmZmljaWVuY3kgUmV0ZW50aW9uIiwgY29sb3VyPSJPcmlnaW4iKSsNCiAgeWxpbSgwLjcsIDEpOyBUUDNfVG9sUEFNLnBsb3QNCmBgYA0KDQoNCiMjIyMgU2F2ZSBSZXN1bHRzDQpgYGB7cn0NCiMjQ29tYmluZSBSZXN1bHRzDQpUb2xfVFAzLnJlczwtcmJpbmQoVG9sX1BBTV9UUDMucmVzLCBUb2xfU3ltX1RQMy5yZXMsIFRvbF9DaGxfVFAzLnJlcykNClRvbC5wYWlyLnJlc19UUDM8LXJiaW5kKFRvbF9QQU0ucGFpcl9UUDMucmVzLCBUb2xfU3ltLnBhaXJfVFAzLnJlcywgVG9sX0NobC5wYWlyX1RQMy5yZXMpDQoNCiMjQWRkIFRpbWVwb2ludA0KVG9sX1RQMy5yZXMkVGltZVA8LXJlcCgiVFAzIiwgbnJvdyhUb2xfVFAzLnJlcykpDQpUb2wucGFpci5yZXNfVFAzJFRpbWVQPC1yZXAoIlRQMyIsIG5yb3coVG9sLnBhaXIucmVzX1RQMykpDQoNCmBgYA0KDQoNCiMjIyBUUDQNCmBgYHtyfQ0KIyNTdWJzZXQgVGltZXBvaW50IDQNClRoZXJtX1RQNDwtc3Vic2V0KFRoZXJtX0gsIFRpbWVQPT0iVFA0IikNCmBgYA0KDQoNCiMjIyMgU3ltYmlvbnRzDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1fVFA0JFN5bS5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRoZXJtX1RQNCRTeW0ucHJvcCkNCiNOb3Qgbm9ybWFsDQoNCmhpc3QobG9nKFRoZXJtX1RQNCRTeW0ucHJvcCsxKSkNCnNoYXBpcm8udGVzdChsb2coVGhlcm1fVFA0JFN5bS5wcm9wKzEpKQ0KI05vcm1hbA0KDQojI01vZGVsIHdpdGggbG9nICsxIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfU3ltLmxtZV9UUDQ8LWxtZXIobG9nKFN5bS5wcm9wKzEpfk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1UaGVybV9UUDQpDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfU3ltLmxtZV9yZXNfVFA0IDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gVG9sX1N5bS5sbWVfVFA0LCBwbG90ID0gRikNCnBsb3QoVG9sX1N5bS5sbWVfcmVzX1RQNCkNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW0ubG1lX1RQNCkNCg0KZXRhX3NxdWFyZWQoVG9sX1N5bS5sbWVfVFA0KQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9UUDQucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX1N5bS5sbWVfVFA0KSRjb2VmZmljaWVudHNbLTEsXSkNClRvbF9TeW1fVFA0LnJlcyRQcmVkaWN0b3I8LWMoIk9yaWdpbiIsICJTaXRlIiwgIk9yaWdpbiB4IFNpdGUiKQ0KVG9sX1N5bV9UUDQucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TeW0ubG1lX1RQNCkkRXRhMikNClRvbF9TeW1fVFA0LnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udCBSZXRlbnRpb24iLCBucm93KFRvbF9TeW1fVFA0LnJlcykpDQoNCmBgYA0KDQpgYGB7cn0NCiMjUGFpcndpc2UgQ29tcGFyaXNvbnMgb2YgSW50ZXJlc3QNCiNOYXRpdmUgdnMgVHJhbnNwbGFudCB3aXRoaW4gYSBTaXRlDQpUb2xfU3ltLnBhaXJfVFA0PC1lbW1lYW5zKFRvbF9TeW0ubG1lX1RQNCwgcGFpcndpc2V+T3JpZ2luIHwgU2l0ZSkNClRvbF9TeW0ucGFpcl9UUDQNCg0KI0NhbGN1bGF0ZSBzdGFuZGFyZGl6ZWQgZWZmZWN0IHNpemVzIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KVG9sX1N5bS5wYWlyLmVzX1RQNDwtZGF0YS5mcmFtZShlZmZfc2l6ZShUb2xfU3ltLnBhaXJfVFA0LCBzaWdtYT1zaWdtYShUb2xfU3ltLmxtZV9UUDQpLCBlZGY9ZGYucmVzaWR1YWwoVG9sX1N5bS5sbWVfVFA0KSkpDQpUb2xfU3ltLnBhaXIuZXNfVFA0DQpUb2xfU3ltLnBhaXIuZXNfVFA0PC1Ub2xfU3ltLnBhaXIuZXNfVFA0ICU+JSBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0LnNlID0gY29udHJhc3QsIFNFLmVzID0gU0UsIGRmLmVzID0gZGYpDQoNCiMjU2F2ZSBSZXN1bHRzDQpUb2xfU3ltLnBhaXJfVFA0LnJlczwtbWVyZ2UoZGF0YS5mcmFtZShUb2xfU3ltLnBhaXJfVFA0JGNvbnRyYXN0cyksIFRvbF9TeW0ucGFpci5lc19UUDRbLC1jKDEpXSkNClRvbF9TeW0ucGFpcl9UUDQucmVzJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250IFJldGVudGlvbiIsIG5yb3coVG9sX1N5bS5wYWlyX1RQNC5yZXMpKQ0KDQojI0FkZCBTaWduaWZpY2FuY2UgbGV2ZWxzDQpUb2xfU3ltLnBhaXJfVFA0LnJlcyRTaWc8LWlmZWxzZShUb2xfU3ltLnBhaXJfVFA0LnJlcyRwLnZhbHVlPDAuMDAxLCAiKioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfU3ltLnBhaXJfVFA0LnJlcyRwLnZhbHVlPDAuMDEsICIqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9TeW0ucGFpcl9UUDQucmVzJHAudmFsdWU8MC4wNSwgIioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1N5bS5wYWlyX1RQNC5yZXMkcC52YWx1ZTwwLjEsICItIiwgTkEpKSkpDQpUb2xfU3ltLnBhaXJfVFA0LnJlcw0KYGBgDQoNCg0KYGBge3IgUGxvdCBTeW1iaW9udCBSZXRlbnRpb24gVFA0fQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDRfVG9sU3ltLnN1bTwtc3VtbWFyeVNFKFRoZXJtX1RQNCwgbWVhc3VyZXZhcj0iU3ltLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVFA0X1RvbFN5bS5wbG90PC1nZ3Bsb3QoVFA0X1RvbFN5bS5zdW0sIGFlcyh4PVNpdGUsIHk9U3ltLnByb3AsIGNvbG91cj1TaXRlLk9yaWcpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TeW0ucHJvcC1zZSwgeW1heD1TeW0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIE9yaWdpbiIsIHk9IlN5bWJpb250IFJldGVudGlvbiIsIGNvbG91cj0iT3JpZ2luIikrDQogIHlsaW0oMCwgMSk7IFRQNF9Ub2xTeW0ucGxvdA0KYGBgDQoNCg0KIyMjIyBDaGxvcm9waHlsbA0KYGBge3J9DQojQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRoZXJtX1RQNCRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUaGVybV9UUDQkQ2hsLnByb3ApDQojTm90IG5vcm1hbA0KDQpoaXN0KGxvZyhUaGVybV9UUDQkQ2hsLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRoZXJtX1RQNCRDaGwucHJvcCsxKSkNCiMjTmVhcmx5IG5vcm1hbA0KDQojI01vZGVsIHdpdGggbG9nICsxIHRyYW5zZm9ybWF0aW9uDQojRnVuY3Rpb24gb2YgU2l0ZSBhbmQgT3JpZ2luLCB3aXRoIEdlbm90eXBlIGFzIGEgUmFuZG9tIGVmZmVjdA0KI0ludGVyYWN0aW9uIGJldHdlZW4gU2l0ZSBhbmQgT3JpZ2luDQpUb2xfQ2hsLmxtZV9UUDQ8LWxtZXIobG9nKENobC5wcm9wKzEpfk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1UaGVybV9UUDQpDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfQ2hsLmxtZV9yZXNfVFA0IDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gVG9sX0NobC5sbWVfVFA0LCBwbG90ID0gRikNCnBsb3QoVG9sX0NobC5sbWVfcmVzX1RQNCkNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGwubG1lX1RQNCkNCg0KZXRhX3NxdWFyZWQoVG9sX0NobC5sbWVfVFA0KQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX0NobF9UUDQucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX0NobC5sbWVfVFA0KSRjb2VmZmljaWVudHNbLTEsXSkNClRvbF9DaGxfVFA0LnJlcyRQcmVkaWN0b3I8LWMoIk9yaWdpbiIsICJTaXRlIiwgIk9yaWdpbiB4IFNpdGUiKQ0KVG9sX0NobF9UUDQucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGwubG1lX1RQNCkkRXRhMikNClRvbF9DaGxfVFA0LnJlcyRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCBSZXRlbnRpb24iLCBucm93KFRvbF9DaGxfVFA0LnJlcykpDQoNCmBgYA0KDQpgYGB7cn0NCiMjUGFpcndpc2UgQ29tcGFyaXNvbnMgb2YgSW50ZXJlc3QNCiNOYXRpdmUgdnMgVHJhbnNwbGFudCB3aXRoaW4gYSBTaXRlDQpUb2xfQ2hsLnBhaXJfVFA0PC1lbW1lYW5zKFRvbF9DaGwubG1lX1RQNCwgcGFpcndpc2V+T3JpZ2luIHwgU2l0ZSkNClRvbF9DaGwucGFpcl9UUDQNCg0KI0NhbGN1bGF0ZSBzdGFuZGFyZGl6ZWQgZWZmZWN0IHNpemVzIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KVG9sX0NobC5wYWlyLmVzX1RQNDwtZGF0YS5mcmFtZShlZmZfc2l6ZShUb2xfQ2hsLnBhaXJfVFA0LCBzaWdtYT1zaWdtYShUb2xfQ2hsLmxtZV9UUDQpLCBlZGY9ZGYucmVzaWR1YWwoVG9sX0NobC5sbWVfVFA0KSkpDQpUb2xfQ2hsLnBhaXIuZXNfVFA0DQpUb2xfQ2hsLnBhaXIuZXNfVFA0PC1Ub2xfQ2hsLnBhaXIuZXNfVFA0ICU+JSBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0LnNlID0gY29udHJhc3QsIFNFLmVzID0gU0UsIGRmLmVzID0gZGYpDQoNCiMjU2F2ZSBSZXN1bHRzDQpUb2xfQ2hsLnBhaXJfVFA0LnJlczwtbWVyZ2UoZGF0YS5mcmFtZShUb2xfQ2hsLnBhaXJfVFA0JGNvbnRyYXN0cyksIFRvbF9DaGwucGFpci5lc19UUDRbLC1jKDEpXSkNClRvbF9DaGwucGFpcl9UUDQucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIFJldGVudGlvbiIsIG5yb3coVG9sX0NobC5wYWlyX1RQNC5yZXMpKQ0KDQojI0FkZCBTaWduaWZpY2FuY2UgbGV2ZWxzDQpUb2xfQ2hsLnBhaXJfVFA0LnJlcyRTaWc8LWlmZWxzZShUb2xfQ2hsLnBhaXJfVFA0LnJlcyRwLnZhbHVlPDAuMDAxLCAiKioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfQ2hsLnBhaXJfVFA0LnJlcyRwLnZhbHVlPDAuMDEsICIqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9DaGwucGFpcl9UUDQucmVzJHAudmFsdWU8MC4wNSwgIioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX0NobC5wYWlyX1RQNC5yZXMkcC52YWx1ZTwwLjEsICItIiwgTkEpKSkpDQpUb2xfQ2hsLnBhaXJfVFA0LnJlcw0KYGBgDQoNCg0KYGBge3IgUGxvdCBDaGxvcm9waHlsbCBSZXRlbnRpb24gVFA0fQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDRfVG9sQ2hsLnN1bTwtc3VtbWFyeVNFKFRoZXJtX1RQNCwgbWVhc3VyZXZhcj0iQ2hsLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVFA0X1RvbENobC5wbG90PC1nZ3Bsb3QoVFA0X1RvbENobC5zdW0sIGFlcyh4PVNpdGUsIHk9Q2hsLnByb3AsIGNvbG91cj1TaXRlLk9yaWcpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIE9yaWdpbiIsIHk9IkNobG9yb3BoeWxsIFJldGVudGlvbiIsIGNvbG91cj0iT3JpZ2luIikrDQogIHlsaW0oMCwgMC4zNSk7IFRQNF9Ub2xDaGwucGxvdA0KYGBgDQoNCg0KIyMjIyBGdkZtDQpgYGB7cn0NCiNDaGVjayBub3JtYWxpdHkNCmhpc3QoVGhlcm1fVFA0JFBBTS5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRoZXJtX1RQNCRQQU0ucHJvcCkNCiNOb3Qgbm9ybWFsDQoNCmhpc3QoVGhlcm1fVFA0JFBBTS5wcm9wXjIpDQpzaGFwaXJvLnRlc3QoVGhlcm1fVFA0JFBBTS5wcm9wXjIpDQojI1N0aWxsIG5vdCBub3JtYWwNCg0KIyNNb2RlbCB3aXRoIHNxdWFyZWQgdHJhbnNmb3JtYXRpb24gdG8gaW1wcm92ZSByZXNpZHVhbHMNCiNGdW5jdGlvbiBvZiBTaXRlIGFuZCBPcmlnaW4sIHdpdGggR2Vub3R5cGUgYXMgYSBSYW5kb20gZWZmZWN0DQojSW50ZXJhY3Rpb24gYmV0d2VlbiBTaXRlIGFuZCBPcmlnaW4NClRvbF9QQU0ubG1lX1RQNDwtbG1lcihQQU0ucHJvcF4yfk9yaWdpbipTaXRlKygxfEdlbm90eXBlKSwgZGF0YT1UaGVybV9UUDQpDQoNCiMjQ2hlY2sgcmVzaWR1YWxzDQpUb2xfUEFNLmxtZV9yZXNfVFA0IDwtIHNpbXVsYXRlUmVzaWR1YWxzKGZpdHRlZE1vZGVsID0gVG9sX1BBTS5sbWVfVFA0LCBwbG90ID0gRikNCnBsb3QoVG9sX1BBTS5sbWVfcmVzX1RQNCkNCg0KIyNNb2RlbCByZXN1bHRzDQpzdW1tYXJ5KFRvbF9QQU0ubG1lX1RQNCkNCg0KZXRhX3NxdWFyZWQoVG9sX1BBTS5sbWVfVFA0KQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1BBTV9UUDQucmVzPC1kYXRhLmZyYW1lKHN1bW1hcnkoVG9sX1BBTS5sbWVfVFA0KSRjb2VmZmljaWVudHNbLTEsXSkNClRvbF9QQU1fVFA0LnJlcyRQcmVkaWN0b3I8LWMoIk9yaWdpbiIsICJTaXRlIiwgIk9yaWdpbiB4IFNpdGUiKQ0KVG9sX1BBTV9UUDQucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9QQU0ubG1lX1RQNCkkRXRhMikNClRvbF9QQU1fVFA0LnJlcyRSZXNwb25zZTwtcmVwKCJGdkZtIFJldGVudGlvbiIsIG5yb3coVG9sX1BBTV9UUDQucmVzKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyNQYWlyd2lzZSBDb21wYXJpc29ucyBvZiBJbnRlcmVzdA0KI05hdGl2ZSB2cyBUcmFuc3BsYW50IHdpdGhpbiBhIFNpdGUNClRvbF9QQU0ucGFpcl9UUDQ8LWVtbWVhbnMoVG9sX1BBTS5sbWVfVFA0LCBwYWlyd2lzZX5PcmlnaW4gfCBTaXRlKQ0KVG9sX1BBTS5wYWlyX1RQNA0KDQojQ2FsY3VsYXRlIHN0YW5kYXJkaXplZCBlZmZlY3Qgc2l6ZXMgZm9yIHBhaXJ3aXNlIGNvbXBhcmlzb25zDQpUb2xfUEFNLnBhaXIuZXNfVFA0PC1kYXRhLmZyYW1lKGVmZl9zaXplKFRvbF9QQU0ucGFpcl9UUDQsIHNpZ21hPXNpZ21hKFRvbF9QQU0ubG1lX1RQNCksIGVkZj1kZi5yZXNpZHVhbChUb2xfUEFNLmxtZV9UUDQpKSkNClRvbF9QQU0ucGFpci5lc19UUDQNClRvbF9QQU0ucGFpci5lc19UUDQ8LVRvbF9QQU0ucGFpci5lc19UUDQgJT4lIGRwbHlyOjpyZW5hbWUoY29udHJhc3Quc2UgPSBjb250cmFzdCwgU0UuZXMgPSBTRSwgZGYuZXMgPSBkZikNCg0KIyNTYXZlIFJlc3VsdHMNClRvbF9QQU0ucGFpcl9UUDQucmVzPC1tZXJnZShkYXRhLmZyYW1lKFRvbF9QQU0ucGFpcl9UUDQkY29udHJhc3RzKSwgVG9sX1BBTS5wYWlyLmVzX1RQNFssLWMoMSldKQ0KVG9sX1BBTS5wYWlyX1RQNC5yZXMkUmVzcG9uc2U8LXJlcCgiRnZGbSBSZXRlbnRpb24iLCBucm93KFRvbF9QQU0ucGFpcl9UUDQucmVzKSkNCg0KIyNBZGQgU2lnbmlmaWNhbmNlIGxldmVscw0KVG9sX1BBTS5wYWlyX1RQNC5yZXMkU2lnPC1pZmVsc2UoVG9sX1BBTS5wYWlyX1RQNC5yZXMkcC52YWx1ZTwwLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVG9sX1BBTS5wYWlyX1RQNC5yZXMkcC52YWx1ZTwwLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShUb2xfUEFNLnBhaXJfVFA0LnJlcyRwLnZhbHVlPDAuMDUsICIqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFRvbF9QQU0ucGFpcl9UUDQucmVzJHAudmFsdWU8MC4xLCAiLSIsIE5BKSkpKQ0KVG9sX1BBTS5wYWlyX1RQNC5yZXMNCmBgYA0KDQoNCmBgYHtyIFBsb3QgRnZGbSBSZXRlbnRpb24gVFA0fQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgT3JpZ2luDQpUUDRfVG9sUEFNLnN1bTwtc3VtbWFyeVNFKFRoZXJtX1RQNCwgbWVhc3VyZXZhcj0iUEFNLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZSIsICJPcmlnaW4iLCAiU2l0ZS5PcmlnIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVFA0X1RvbFBBTS5wbG90PC1nZ3Bsb3QoVFA0X1RvbFBBTS5zdW0sIGFlcyh4PVNpdGUsIHk9UEFNLnByb3AsIGNvbG91cj1TaXRlLk9yaWcpKSArIA0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1QQU0ucHJvcC1zZSwgeW1heD1QQU0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3osIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9IlNpdGUgYW5kIE9yaWdpbiIsIHk9IlBob3RvY2hlbWljYWwgRWZmaWNpZW5jeSBSZXRlbnRpb24iLCBjb2xvdXI9Ik9yaWdpbiIpKw0KICB5bGltKDAuNiwgMSk7IFRQNF9Ub2xQQU0ucGxvdA0KYGBgDQoNCg0KIyMjIyBTYXZlIFJlc3VsdHMNCmBgYHtyfQ0KIyNDb21iaW5lIFJlc3VsdHMNClRvbF9UUDQucmVzPC1yYmluZChUb2xfUEFNX1RQNC5yZXMsIFRvbF9TeW1fVFA0LnJlcywgVG9sX0NobF9UUDQucmVzKQ0KVG9sLnBhaXIucmVzX1RQNDwtcmJpbmQoVG9sX1BBTS5wYWlyX1RQNC5yZXMsIFRvbF9TeW0ucGFpcl9UUDQucmVzLCBUb2xfQ2hsLnBhaXJfVFA0LnJlcykNCg0KIyNBZGQgVGltZXBvaW50DQpUb2xfVFA0LnJlcyRUaW1lUDwtcmVwKCJUUDQiLCBucm93KFRvbF9UUDQucmVzKSkNClRvbC5wYWlyLnJlc19UUDQkVGltZVA8LXJlcCgiVFA0IiwgbnJvdyhUb2wucGFpci5yZXNfVFA0KSkNCg0KYGBgDQoNCg0KIyMjIFBlcmNlbnQgRGlmZmVyZW5jZSBpbiBGdi9GbQ0KRm9jdXMgb24gRnYvRm0gYXQgS0wgVFAgMSBhbmQgMiB3aGVyZSBkaWZmZXJlbmNlIHdlcmUgc2lnbmlmaWNhbnQNCg0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBHZW5vdHlwZSwgT3JpZ2luLCBTaXRlLCBhbmQgVGltZXBvaW50DQpUb2wuUEFNLnN1bTwtc3VtbWFyeVNFKFRoZXJtX0gsIG1lYXN1cmV2YXI9IlBBTS5wcm9wIiwgZ3JvdXB2YXJzPWMoIkdlbm90eXBlIiwgIk9yaWdpbiIsICJTaXRlIiwgIlRpbWVQIiksIG5hLnJtPVRSVUUpDQoNCiMjUmVtb3ZlIEluaXRpYWwgVGltZXBvaW50DQpUb2wuUEFNLnN1bTwtVG9sLlBBTS5zdW1bLWMod2hpY2goVG9sLlBBTS5zdW0kVGltZVA9PSJJTiIpKSxdDQoNCiMjQ2FsY3VsYXRlIFBlcmNlbnQgRGlmZmVyZW5jZSBiZXR3ZWVuIE5hdGl2ZSBhbmQgVHJhbnNwbGFudCBieSBHZW5vdHlwZQ0KVG9sLlBBTS5kaWY8LVRvbC5QQU0uc3VtW3doaWNoKFRvbC5QQU0uc3VtJE9yaWdpbj09Ik5hdGl2ZSIpLCBjKDEsMyw0LDYpXQ0KVG9sLlBBTS5kaWY8LVRvbC5QQU0uZGlmICU+JSBkcGx5cjo6cmVuYW1lKFBBTV9OID0gUEFNLnByb3ApDQpUb2wuUEFNLmRpZiRQQU1fVDwtVG9sLlBBTS5zdW0kUEFNLnByb3Bbd2hpY2goVG9sLlBBTS5zdW0kT3JpZ2luPT0iVHJhbnNwbGFudCIpXQ0KDQojI0tMDQpUb2wuUEFNLmRpZl9LTDwtc3Vic2V0KFRvbC5QQU0uZGlmLCBTaXRlPT0iS0wiKQ0KVG9sLlBBTS5kaWZfS0wkUGVyYy5JbmM8LSgoVG9sLlBBTS5kaWZfS0wkUEFNX1QtVG9sLlBBTS5kaWZfS0wkUEFNX04pL1RvbC5QQU0uZGlmX0tMJFBBTV9OKSoxMDANClRvbC5QQU0uZGlmX0tMDQoNCiMjTWVhbiBhbmQgU3RhbmRhcmQgRXJyb3IgYnkgVGltZXBvaW50DQpUb2wuUEFNLmRpZl9LTC5zdW08LXN1bW1hcnlTRShUb2wuUEFNLmRpZl9LTCwgbWVhc3VyZXZhcj0iUGVyYy5JbmMiLCBncm91cHZhcnM9YygiVGltZVAiKSwgbmEucm09VFJVRSkNClRvbC5QQU0uZGlmX0tMLnN1bQ0KYGBgDQoNCg0KIyBQZXJmb3JtYW5jZSBFZmZlY3QgU2l6ZXMNCg0KIyMjIEN1cnJlbnQgdnMgT3JpZ2luYWwgU2l0ZQ0KYGBge3J9DQojI0NvbWJpbmUgUmVzdWx0cw0KR3Jvd3RoLlRQLnJlczwtcmJpbmQoVExFX1RQMS4yLnJlcywgVExFX1RQMy40LnJlcykNCkdyb3d0aC5UUC5yZXM8LUdyb3d0aC5UUC5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoVGltZVAgPSBUaW1lcG9pbnQpDQpUb2xfVFAucmVzPC1yYmluZChUb2xfVFAxLnJlcywgVG9sX1RQMi5yZXMsIFRvbF9UUDMucmVzLCBUb2xfVFA0LnJlcykNClBlcmYucmVzPC1yYmluZChHcm93dGguVFAucmVzLCBUb2xfVFAucmVzKQ0KUGVyZi5yZXM8LVBlcmYucmVzICU+JSBkcGx5cjo6cmVuYW1lKHAgPSBQci4uLnQuLikNCg0KIyNSZXNwb25zZXMgZm9yIEZpZ3VyZQ0KUGVyZi5yZXMucGxvdDwtUGVyZi5yZXNbLWMod2hpY2goUGVyZi5yZXMkUmVzcG9uc2U9PSJDaGxvcm9waHlsbCBSZXRlbnRpb24iKSksXQ0KDQojI0FkZCBTaWduaWZpY2FuY2UgbGV2ZWxzDQpQZXJmLnJlcy5wbG90JFNpZzwtaWZlbHNlKFBlcmYucmVzLnBsb3QkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShQZXJmLnJlcy5wbG90JHA8MC4wMSwgIioqIiwgDQogICAgICAgICAgICBpZmVsc2UoUGVyZi5yZXMucGxvdCRwPDAuMDUsICIqIiwgaWZlbHNlKFBlcmYucmVzLnBsb3QkcDwwLjEsICItIiwgTkEpKSkpDQoNCiMjU2V0IE9yZGVyDQpQZXJmLnJlcy5wbG90JFJlc3BvbnNlPC1mYWN0b3IoUGVyZi5yZXMucGxvdCRSZXNwb25zZSwgbGV2ZWxzPWMoIkdyb3d0aCIsICJGdkZtIFJldGVudGlvbiIsICJTeW1iaW9udCBSZXRlbnRpb24iKSwgb3JkZXJlZD1UUlVFKQ0KDQojI01hdGNoIEdyb3d0aCBUaW1lcG9pbnRzDQpQZXJmLnJlcy5wbG90JFRpbWVQW3doaWNoKFBlcmYucmVzLnBsb3QkVGltZVA9PSJUUDFfMiIpXTwtIlRQMiINClBlcmYucmVzLnBsb3QkVGltZVBbd2hpY2goUGVyZi5yZXMucGxvdCRUaW1lUD09IlRQM180IildPC0iVFA0Ig0KDQpgYGANCg0KDQojIyMjIFBsb3QgRWZmZWN0IFNpemUgb2YgT3JpZ2luIGFuZCBTaXRlDQpgYGB7ciBQbG90IE9yaWdpbiBhbmQgU2l0ZSBFZmZlY3QgU2l6ZXN9DQpQZXJmLlNpdGUuT3JpZy5FUy5wbG90PC1nZ3Bsb3QoUGVyZi5yZXMucGxvdCwgYWVzKGZpbGw9UHJlZGljdG9yLCB5PUV0YVNxLCB4PVRpbWVQKSkgKyANCiAgICBnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siLCBzdGF0PSJpZGVudGl0eSIpKw0KICBmYWNldF93cmFwKHZhcnMoUmVzcG9uc2UpKSsNCiAgdGhlbWVfYncoKSsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImluZGlhbnJlZDIiLCAibWVkaXVtcHVycGxlMyIsICJzdGVlbGJsdWUyIikpKw0KICB0aGVtZShzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudGl0bGUuc3opLA0KICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9IndoaXRlIiksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPWMoLjA4LCAuOCksIA0KICAgICAgICBwYW5lbC5ncmlkLm1ham9yLng9ZWxlbWVudF9ibGFuaygpKSsNCiAgIGxhYnMoeD0iVGltZSBQb2ludCIsIHk9ZXhwcmVzc2lvbihwYXN0ZSgiUHJlZGljdG9yIEVmZmVjdCBTaXplIChwIiwgZXRhXjIsICIpIikpLCBjb2xvdXI9IlByZWRpY3RvciIpKw0KICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBwb3NpdGlvbj1wb3NpdGlvbl9zdGFjayh2anVzdD0wLjUpLCBzaXplPXNpZy5zeik7IFBlcmYuU2l0ZS5PcmlnLkVTLnBsb3QNCmBgYA0KDQoNCiMjIyBOYXRpdmUgdnMgVHJhbnNwbGFudA0KYGBge3J9DQojI0NvbWJpbmUgUGFpcndpc2UgUmVzdWx0cw0KR3Jvd3RoLnBhaXIucmVzPC1yYmluZChUTEUucGFpcl9UUDEuMi5yZXMsIFRMRS5wYWlyX1RQMy40LnJlcykNClRvbC5wYWlyLnJlczwtcmJpbmQoVG9sLnBhaXIucmVzX1RQMSwgVG9sLnBhaXIucmVzX1RQMiwgVG9sLnBhaXIucmVzX1RQMywgVG9sLnBhaXIucmVzX1RQNCkNClBlcmYucGFpci5yZXM8LXJiaW5kKEdyb3d0aC5wYWlyLnJlc1ssYygxOjEzLCAxNSwgMTQpXSwgVG9sLnBhaXIucmVzKQ0KDQojI1Jlc3BvbnNlcyBmb3IgRmlndXJlDQpQZXJmLnBhaXIucmVzLnBsb3Q8LVBlcmYucGFpci5yZXNbLWMod2hpY2goUGVyZi5wYWlyLnJlcyRSZXNwb25zZT09IkNobG9yb3BoeWxsIFJldGVudGlvbiIpKSxdDQoNCiMjQWRkIFNpZ25pZmljYW5jZQ0KUGVyZi5wYWlyLnJlcy5wbG90JFNpZ25pZmljYW50PC1pZmVsc2UoUGVyZi5wYWlyLnJlcy5wbG90JHAudmFsdWU8MC4wNSwgInNpZyIsICJub24iKQ0KDQojI1NldCBPcmRlcg0KUGVyZi5wYWlyLnJlcy5wbG90JFJlc3BvbnNlPC1mYWN0b3IoUGVyZi5wYWlyLnJlcy5wbG90JFJlc3BvbnNlLCBsZXZlbHM9YygiR3Jvd3RoIiwgIkZ2Rm0gUmV0ZW50aW9uIiwgIlN5bWJpb250IFJldGVudGlvbiIpLCBvcmRlcmVkPVRSVUUpDQoNCiMjTWF0Y2ggR3Jvd3RoIFRpbWVwb2ludHMNClBlcmYucGFpci5yZXMucGxvdCRUaW1lUFt3aGljaChQZXJmLnBhaXIucmVzLnBsb3QkVGltZVA9PSJUUDFfMiIpXTwtIlRQMiINClBlcmYucGFpci5yZXMucGxvdCRUaW1lUFt3aGljaChQZXJmLnBhaXIucmVzLnBsb3QkVGltZVA9PSJUUDNfNCIpXTwtIlRQNCINCg0KIyNTZXQgRmFjdG9ycw0KUGVyZi5wYWlyLnJlcy5wbG90JFNpdGU8LWZhY3RvcihQZXJmLnBhaXIucmVzLnBsb3QkU2l0ZSwgbGV2ZWxzPWMoIktMIiwgIlNTIiksIG9yZGVyZWQ9VFJVRSkNCg0KYGBgDQoNCg0KIyMjIyBQbG90IEVmZmVjdCBTaXplIG9mIE9yaWdpbg0KYGBge3IgUGxvdCBPcmlnaW4gRWZmZWN0IFNpemVzfQ0KIyNQbG90IEVmZmVjdCBTaXplIGFjcm9zcyBUaW1lcG9pbnRzDQpQZXJmLk9yaWcuRVMucGxvdDwtZ2dwbG90KFBlcmYucGFpci5yZXMucGxvdCwgYWVzKHg9VGltZVAsIHk9ZWZmZWN0LnNpemUpKSArIA0KICBnZW9tX3JlY3QoZmlsbD0iZ3JleTkwIiwgYWxwaGE9MC40LCB4bWluPS1JbmYsIHhtYXg9SW5mLCB5bWluPS0uNCwgeW1heD0wLjQpKw0KICBnZW9tX3JlY3QoZmlsbD0iZ3JleTgwIiwgYWxwaGE9MC40LCB4bWluPS1JbmYsIHhtYXg9SW5mLCB5bWluPS0uMjUsIHltYXg9MC4yNSkrDQogIGdlb21fcmVjdChmaWxsPSJncmV5NzAiLCBhbHBoYT0wLjQsIHhtaW49LUluZiwgeG1heD1JbmYsIHltaW49LS4xLCB5bWF4PTAuMSkrDQogIGdlb21faGxpbmUoeWludGVyY2VwdD0wLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3I9ImdyZXk1MCIsIGxpbmV3aWR0aD0wLjUpKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPWVmZmVjdC5zaXplLVNFLmVzLCB5bWF4PWVmZmVjdC5zaXplK1NFLmVzLCBjb2xvdXI9U2l0ZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX3BvaW50KGFlcyhzaGFwZT1TaWduaWZpY2FudCwgY29sb3VyPVNpdGUpLCBzaXplPXBvaW50LnN6LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSsNCiAgZmFjZXRfd3JhcCh2YXJzKFJlc3BvbnNlKSkrDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPVNpdGUuY29sb3JzLm8pKw0KICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPWMoMSwgMTYpKSsNCiAgdGhlbWVfYncoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPWMoLjEsIC4xKSwNCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwNCiAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6KSwNCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ3aGl0ZSIpLCANCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55PWVsZW1lbnRfYmxhbmsoKSkrDQogIGxhYnMoeD0iVGltZSBQb2ludCIsIHk9Ik9yaWdpbiBFZmZlY3QgU2l6ZSAoQ29oZW4ncyBkKSIsIGNvbG91cj0iU2l0ZSIpKw0KICBndWlkZXMoc2hhcGU9Im5vbmUiKTsgUGVyZi5PcmlnLkVTLnBsb3QNCmBgYA0KTmVlZCB0byBmaXggZG9kZ2UgZm9yIHBvaW50cyBhbmQgZXJyb3IgYmFycw0KDQoNCiMgVHJhZGUgT2Zmcw0KDQojIyMgSW5pdGlhbCBUMSBhbmQgVDINCg0KIyMjIyBBdmVyYWdlIFBlcmZvcm1hbmNlDQpDYWxjdWxhdGluZyB0aGUgYXZlcmFnZSBvZiBHcm93dGggKFRQMSB0byBUUDIpIGFuZCBUaGVybWFsIFRvbGVyYW5jZSAoUmV0ZW50aW9uIG9mIFN5bWJpb250cywgQ2hsb3JvcGh5bGwsIGFuZCBQaG90b2NoZW1pY2FsIEVmZmljaWVuY3kgYXQgVFAxKSBmb3IgZWFjaCBTZXQgKFNpdGUsIEdlbm90eXBlLCBPcmlnaW4pLg0KDQojIyMjIEdyb3d0aA0KYGBge3J9DQojI0F2ZXJhZ2UNCm5hbWVzKEdyb3d0aF9UUDEuMikNClRQMS4yX0dyb3d0aF9TZXQ8LWFnZ3JlZ2F0ZShHcm93dGhfVFAxLjIkVExFX2NtLmRheSwgbGlzdChHcm93dGhfVFAxLjIkU2l0ZSwgR3Jvd3RoX1RQMS4yJEdlbm90eXBlLCBHcm93dGhfVFAxLjIkT3JpZyksIG1lYW4pDQpuYW1lcyhUUDEuMl9Hcm93dGhfU2V0KTwtYygiU2l0ZSIsICJHZW5vdHlwZSIsICJPcmlnIiwgIlRMRV9jbS5kYXkiKQ0KDQojI0FkZCBTdGFuZGFyZCBFcnJvcg0KVFAxLjJfR3Jvd3RoX1NldCRUTEVfc2U8LWFnZ3JlZ2F0ZShHcm93dGhfVFAxLjIkVExFX2NtLmRheSwgbGlzdChHcm93dGhfVFAxLjIkU2l0ZSwgR3Jvd3RoX1RQMS4yJEdlbm90eXBlLCBHcm93dGhfVFAxLjIkT3JpZyksIHN0ZC5lcnJvcilbLDRdDQpgYGANCg0KDQojIyMjIFRvbGVyYW5jZQ0KYGBge3J9DQojI0F2ZXJhZ2UNCm5hbWVzKFRoZXJtX1RQMSkNClQxX1RoZXJtX1NldDwtYWdncmVnYXRlKFRoZXJtX1RQMVssYygxOToyMSldLCBsaXN0KFRoZXJtX1RQMSRTaXRlLCBUaGVybV9UUDEkR2Vub3R5cGUsIFRoZXJtX1RQMSRPcmlnKSwgbWVhbikNCm5hbWVzKFQxX1RoZXJtX1NldCk8LWMoIlNpdGUiLCAiR2Vub3R5cGUiLCAiT3JpZyIsICJDaGwucHJvcCIsICJTeW0ucHJvcCIsICJQQU0ucHJvcCIpDQoNCiMjQWRkIFN0YW5kYXJkIEVycm9yDQpUMV9UaGVybV9TZXQkQ2hsX3NlPC1hZ2dyZWdhdGUoVGhlcm1fVFAxJENobC5wcm9wLCBsaXN0KFRoZXJtX1RQMSRTaXRlLCBUaGVybV9UUDEkR2Vub3R5cGUsIFRoZXJtX1RQMSRPcmlnKSwgc3RkLmVycm9yKVssNF0NCg0KVDFfVGhlcm1fU2V0JFN5bV9zZTwtYWdncmVnYXRlKFRoZXJtX1RQMSRTeW0ucHJvcCwgbGlzdChUaGVybV9UUDEkU2l0ZSwgVGhlcm1fVFAxJEdlbm90eXBlLCBUaGVybV9UUDEkT3JpZyksIHN0ZC5lcnJvcilbLDRdDQoNClQxX1RoZXJtX1NldCRQQU1fc2U8LWFnZ3JlZ2F0ZShUaGVybV9UUDEkUEFNLnByb3AsIGxpc3QoVGhlcm1fVFAxJFNpdGUsIFRoZXJtX1RQMSRHZW5vdHlwZSwgVGhlcm1fVFAxJE9yaWcpLCBzdGQuZXJyb3IpWyw0XQ0KYGBgDQoNCg0KIyMjIyBNZXJnZSBHcm93dGggYW5kIFRvbGVyYW5jZSANCmBgYHtyfQ0KVFAxLjJfUGVyZl9TZXQ8LW1lcmdlKFRQMS4yX0dyb3d0aF9TZXQsIFQxX1RoZXJtX1NldCwgYWxsPVRSVUUpDQpUUDEuMl9QZXJmX1NldCRTZXQ8LXBhc3RlKFRQMS4yX1BlcmZfU2V0JFNpdGUsIFRQMS4yX1BlcmZfU2V0JEdlbm90eXBlLCBUUDEuMl9QZXJmX1NldCRPcmlnLCBzZXA9Ii4iKQ0KDQojI1NldCBmYWN0b3IgdmFyaWFibGVzDQpUUDEuMl9QZXJmX1NldCRTaXRlPC1mYWN0b3IoVFAxLjJfUGVyZl9TZXQkU2l0ZSwgbGV2ZWxzPWMoIktMIiwgIlNTIikpDQpUUDEuMl9QZXJmX1NldCRHZW5vdHlwZTwtZmFjdG9yKFRQMS4yX1BlcmZfU2V0JEdlbm90eXBlLCBsZXZlbHM9YygiQUM4IiwgIkFDMTAiLCAiQUMxMiIpKQ0KVFAxLjJfUGVyZl9TZXQkT3JpZzwtZmFjdG9yKFRQMS4yX1BlcmZfU2V0JE9yaWcsIGxldmVscz1jKCJOIiwgIlQiKSkNCg0KIyNBZGQgYSBTYW1wbGUgU2V0IFZhcmlhYmxlDQpUUDEuMl9QZXJmX1NldCRTZXQ8LXBhc3RlKFRQMS4yX1BlcmZfU2V0JFNpdGUsIFRQMS4yX1BlcmZfU2V0JEdlbm90eXBlLCBUUDEuMl9QZXJmX1NldCRPcmlnLCBzZXA9Ii4iKQ0KVFAxLjJfUGVyZl9TZXQkU2V0PC1mYWN0b3IoVFAxLjJfUGVyZl9TZXQkU2V0KQ0KDQojI0FkZCBTaXRlLk9yaWcgdmFyaWFibGUNClRQMS4yX1BlcmZfU2V0JFNpdGUuT3JpZzwtcGFzdGUoVFAxLjJfUGVyZl9TZXQkU2l0ZSwgVFAxLjJfUGVyZl9TZXQkT3JpZywgc2VwPSIuIikNClRQMS4yX1BlcmZfU2V0JFNpdGUuT3JpZzwtZmFjdG9yKFRQMS4yX1BlcmZfU2V0JFNpdGUuT3JpZywgbGV2ZWxzPWMoIktMLk4iLCAiS0wuVCIsICJTUy5OIiwgIlNTLlQiKSkNCg0KYGBgDQoNCg0KIyMjIENvcnJlbGF0aW9uIGJldHdlZW4gR3Jvd3RoIGFuZCBUb2xlcmFuY2UNCg0KIyMjIyBTeW1iaW9udCBSZXRlbnRpb24NCg0KYGBge3J9DQpjb3IudGVzdChUUDEuMl9QZXJmX1NldCRUTEVfY20uZGF5LCBUUDEuMl9QZXJmX1NldCRTeW0ucHJvcCwgbWV0aG9kPSJzcGVhcm1hbiIpDQpgYGANCg0KDQpgYGB7ciBQbG90IEdyb3d0aCB2cyBTeW1iaW9udCBSZXRlbnRpb24gVDEyfQ0KVFAxLjJfVExFX1N5bS5wbG90PC1nZ3Bsb3QoVFAxLjJfUGVyZl9TZXQsIGFlcyh4PVRMRV9jbS5kYXksIHk9U3ltLnByb3ApKSArIA0KICAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIGNvbG9yPSIjQUExODVBRkYiLCBmaWxsPSIjRjhEN0JGRkYiLCBzZT1UUlVFKSsNCiAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1TaXRlLk9yaWcsIHNoYXBlPUdlbm90eXBlKSxzaXplPXBvaW50LnN6KSsNCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1HZW5vLnNoYXBlcy5vKSsNCiAgIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSkrDQogIGxhYnMoeD1leHByZXNzaW9uKHBhc3RlKCdHcm93dGggUmF0ZSAoY20gZGF5J14tMSoiKSIpKSwgDQogICAgICAgeT0iU3ltYmlvbnQgUmV0ZW50aW9uIiwgDQogICAgICAgY29sb3VyPSJTaXRlIE9yaWdpbiIpKw0KICAgYW5ub3RhdGUoInRleHQiLCB4ID0gMC4wNywgeSA9IC0uMTUsIGxhYmVsPWV4cHJlc3Npb24oYm9sZGl0YWxpYyhwYXN0ZShyW1NdLCAiID0gLTAuNjE1LCBwID0gMC4wMzciKSkpLCBzaXplPXNpZy5zeiwgaGp1c3QgPSAwKTsgVFAxLjJfVExFX1N5bS5wbG90DQpgYGANCg0KDQojIyMjIENobG9yb3BoeWxsIFJldGVudGlvbg0KDQpgYGB7cn0NCmNvci50ZXN0KFRQMS4yX1BlcmZfU2V0JFRMRV9jbS5kYXksIFRQMS4yX1BlcmZfU2V0JENobC5wcm9wLCBtZXRob2Q9InNwZWFybWFuIikNCmBgYA0KDQoNCmBgYHtyIFBsb3QgR3Jvd3RoIHZzIENobG9yb3BoeWxsIFJldGVudGlvbiBUMTJ9DQpUUDEuMl9UTEVfQ2hsLnBsb3Q8LWdncGxvdChUUDEuMl9QZXJmX1NldCwgYWVzKHg9VExFX2NtLmRheSwgeT1DaGwucHJvcCkpICsgDQogICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgY29sb3I9IiNBQTE4NUFGRiIsIGZpbGw9IiNGOEQ3QkZGRiIsIHNlPVRSVUUpKw0KICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPVNpdGUuT3JpZywgc2hhcGU9R2Vub3R5cGUpLHNpemU9cG9pbnQuc3opKw0KICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPU9yaWcuY29sb3JzLm8pKw0KICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPUdlbm8uc2hhcGVzLm8pKw0KICAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PWV4cHJlc3Npb24ocGFzdGUoJ0dyb3d0aCBSYXRlIChjbSBkYXknXi0xKiIpIikpLCANCiAgICAgICB5PSJDaGxvcm9waHlsbCBSZXRlbnRpb24iLCANCiAgICAgICBjb2xvdXI9IlNpdGUgT3JpZ2luIikrDQogICBhbm5vdGF0ZSgidGV4dCIsIHggPSAwLjA3LCB5ID0gLS4wNSwgbGFiZWw9ZXhwcmVzc2lvbihib2xkaXRhbGljKHBhc3RlKHJbU10sICIgPSAtMC41ODcsIHAgPSAwLjA0OSIpKSksIHNpemU9c2lnLnN6LCBoanVzdCA9IDApOyBUUDEuMl9UTEVfQ2hsLnBsb3QNCmBgYA0KDQoNCiMjIyMgRnZGbSBSZXRlbnRpb24NCg0KYGBge3J9DQpjb3IudGVzdChUUDEuMl9QZXJmX1NldCRUTEVfY20uZGF5LCBUUDEuMl9QZXJmX1NldCRQQU0ucHJvcCwgbWV0aG9kPSJzcGVhcm1hbiIpDQpgYGANCg0KDQpgYGB7ciBQbG90IEdyb3d0aCB2cyBGdkZtIFJldGVudGlvbiBUMTJ9DQpUUDEuMl9UTEVfUEFNLnBsb3Q8LWdncGxvdChUUDEuMl9QZXJmX1NldCwgYWVzKHg9VExFX2NtLmRheSwgeT1QQU0ucHJvcCkpICsgDQogICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgY29sb3I9IiNBQTE4NUFGRiIsIGZpbGw9IiNGOEQ3QkZGRiIsIHNlPVRSVUUpKw0KICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPVNpdGUuT3JpZywgc2hhcGU9R2Vub3R5cGUpLHNpemU9cG9pbnQuc3opKw0KICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPU9yaWcuY29sb3JzLm8pKw0KICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPUdlbm8uc2hhcGVzLm8pKw0KICAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpKSsNCiAgbGFicyh4PWV4cHJlc3Npb24ocGFzdGUoJ0dyb3d0aCBSYXRlIChjbSBkYXknXi0xKiIpIikpLCANCiAgICAgICB5PSJQaG90by4gRWZmaWMuIFJldGVudGlvbiIsIA0KICAgICAgIGNvbG91cj0iU2l0ZSBPcmlnaW4iKSsNCiAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDAuMDcsIHkgPSAwLjcsIGxhYmVsPWV4cHJlc3Npb24oYm9sZGl0YWxpYyhwYXN0ZShyW1NdLCAiID0gLTAuNjc4LCBwID0gMC4wMTkiKSkpLCBzaXplPXNpZy5zeiwgaGp1c3QgPSAwKTsgVFAxLjJfVExFX1BBTS5wbG90DQpgYGANCg0KDQojIyMgRmluYWwgVDMgYW5kIFQ0DQoNCiMjIyMgQXZlcmFnZSBQZXJmb3JtYW5jZQ0KQ2FsY3VsYXRpbmcgdGhlIGF2ZXJhZ2Ugb2YgR3Jvd3RoIChUUDMgdG8gVFA0KSBhbmQgVGhlcm1hbCBUb2xlcmFuY2UgKFJldGVudGlvbiBvZiBTeW1iaW9udHMsIENobG9yb3BoeWxsLCBhbmQgUGhvdG9jaGVtaWNhbCBFZmZpY2llbmN5IGF0IFRQMykgZm9yIGVhY2ggU2V0IChTaXRlLCBHZW5vdHlwZSwgT3JpZ2luKS4NCg0KIyMjIyBHcm93dGgNCmBgYHtyfQ0KIyNBdmVyYWdlDQpuYW1lcyhHcm93dGhfVFAzLjQpDQpUUDMuNF9Hcm93dGhfU2V0PC1hZ2dyZWdhdGUoR3Jvd3RoX1RQMy40JFRMRV9jbS5kYXksIGxpc3QoR3Jvd3RoX1RQMy40JFNpdGUsIEdyb3d0aF9UUDMuNCRHZW5vdHlwZSwgR3Jvd3RoX1RQMy40JE9yaWcpLCBtZWFuKQ0KbmFtZXMoVFAzLjRfR3Jvd3RoX1NldCk8LWMoIlNpdGUiLCAiR2Vub3R5cGUiLCAiT3JpZyIsICJUTEVfY20uZGF5IikNCg0KIyNBZGQgU3RhbmRhcmQgRXJyb3INClRQMy40X0dyb3d0aF9TZXQkVExFX3NlPC1hZ2dyZWdhdGUoR3Jvd3RoX1RQMy40JFRMRV9jbS5kYXksIGxpc3QoR3Jvd3RoX1RQMy40JFNpdGUsIEdyb3d0aF9UUDMuNCRHZW5vdHlwZSwgR3Jvd3RoX1RQMy40JE9yaWcpLCBzdGQuZXJyb3IpWyw0XQ0KYGBgDQoNCg0KIyMjIyBUb2xlcmFuY2UNCmBgYHtyfQ0KIyNBdmVyYWdlDQpuYW1lcyhUaGVybV9UUDQpDQpUNF9UaGVybV9TZXQ8LWFnZ3JlZ2F0ZShUaGVybV9UUDRbLGMoMTk6MjEpXSwgbGlzdChUaGVybV9UUDQkU2l0ZSwgVGhlcm1fVFA0JEdlbm90eXBlLCBUaGVybV9UUDQkT3JpZyksIG1lYW4pDQpuYW1lcyhUNF9UaGVybV9TZXQpPC1jKCJTaXRlIiwgIkdlbm90eXBlIiwgIk9yaWciLCAiQ2hsLnByb3AiLCAiU3ltLnByb3AiLCAiUEFNLnByb3AiKQ0KDQojI0FkZCBTdGFuZGFyZCBFcnJvcg0KVDRfVGhlcm1fU2V0JENobF9zZTwtYWdncmVnYXRlKFRoZXJtX1RQNCRDaGwucHJvcCwgbGlzdChUaGVybV9UUDQkU2l0ZSwgVGhlcm1fVFA0JEdlbm90eXBlLCBUaGVybV9UUDQkT3JpZyksIHN0ZC5lcnJvcilbLDRdDQoNClQ0X1RoZXJtX1NldCRTeW1fc2U8LWFnZ3JlZ2F0ZShUaGVybV9UUDQkU3ltLnByb3AsIGxpc3QoVGhlcm1fVFA0JFNpdGUsIFRoZXJtX1RQNCRHZW5vdHlwZSwgVGhlcm1fVFA0JE9yaWcpLCBzdGQuZXJyb3IpWyw0XQ0KDQpUNF9UaGVybV9TZXQkUEFNX3NlPC1hZ2dyZWdhdGUoVGhlcm1fVFA0JFBBTS5wcm9wLCBsaXN0KFRoZXJtX1RQNCRTaXRlLCBUaGVybV9UUDQkR2Vub3R5cGUsIFRoZXJtX1RQNCRPcmlnKSwgc3RkLmVycm9yKVssNF0NCmBgYA0KDQoNCiMjIyMgTWVyZ2UgR3Jvd3RoIGFuZCBUb2xlcmFuY2UgDQpgYGB7cn0NClRQMy40X1BlcmZfU2V0PC1tZXJnZShUUDMuNF9Hcm93dGhfU2V0LCBUNF9UaGVybV9TZXQsIGFsbD1UUlVFKQ0KVFAzLjRfUGVyZl9TZXQkU2V0PC1wYXN0ZShUUDMuNF9QZXJmX1NldCRTaXRlLCBUUDMuNF9QZXJmX1NldCRHZW5vdHlwZSwgVFAzLjRfUGVyZl9TZXQkT3JpZywgc2VwPSIuIikNCg0KIyNTZXQgZmFjdG9yIHZhcmlhYmxlcw0KVFAzLjRfUGVyZl9TZXQkU2l0ZTwtZmFjdG9yKFRQMy40X1BlcmZfU2V0JFNpdGUsIGxldmVscz1jKCJLTCIsICJTUyIpKQ0KVFAzLjRfUGVyZl9TZXQkR2Vub3R5cGU8LWZhY3RvcihUUDMuNF9QZXJmX1NldCRHZW5vdHlwZSwgbGV2ZWxzPWMoIkFDOCIsICJBQzEwIiwgIkFDMTIiKSkNClRQMy40X1BlcmZfU2V0JE9yaWc8LWZhY3RvcihUUDMuNF9QZXJmX1NldCRPcmlnLCBsZXZlbHM9YygiTiIsICJUIikpDQoNCiMjQWRkIGEgU2FtcGxlIFNldCBWYXJpYWJsZQ0KVFAzLjRfUGVyZl9TZXQkU2V0PC1wYXN0ZShUUDMuNF9QZXJmX1NldCRTaXRlLCBUUDMuNF9QZXJmX1NldCRHZW5vdHlwZSwgVFAzLjRfUGVyZl9TZXQkT3JpZywgc2VwPSIuIikNClRQMy40X1BlcmZfU2V0JFNldDwtZmFjdG9yKFRQMy40X1BlcmZfU2V0JFNldCkNCg0KIyNBZGQgU2l0ZS5PcmlnIHZhcmlhYmxlDQpUUDMuNF9QZXJmX1NldCRTaXRlLk9yaWc8LXBhc3RlKFRQMy40X1BlcmZfU2V0JFNpdGUsIFRQMy40X1BlcmZfU2V0JE9yaWcsIHNlcD0iLiIpDQpUUDMuNF9QZXJmX1NldCRTaXRlLk9yaWc8LWZhY3RvcihUUDMuNF9QZXJmX1NldCRTaXRlLk9yaWcsIGxldmVscz1jKCJLTC5OIiwgIktMLlQiLCAiU1MuTiIsICJTUy5UIikpDQoNCmBgYA0KDQoNCiMjIyBDb3JyZWxhdGlvbiBiZXR3ZWVuIEdyb3d0aCBhbmQgVG9sZXJhbmNlDQoNCiMjIyMgU3ltYmlvbnQgUmV0ZW50aW9uDQoNCmBgYHtyfQ0KY29yLnRlc3QoVFAzLjRfUGVyZl9TZXQkVExFX2NtLmRheSwgVFAzLjRfUGVyZl9TZXQkU3ltLnByb3AsIG1ldGhvZD0ic3BlYXJtYW4iKQ0KYGBgDQoNCg0KYGBge3IgUGxvdCBHcm93dGggdnMgU3ltYmlvbnQgUmV0ZW50aW9uIFQzNH0NClRQMy40X1RMRV9TeW0ucGxvdDwtZ2dwbG90KFRQMy40X1BlcmZfU2V0LCBhZXMoeD1UTEVfY20uZGF5LCB5PVN5bS5wcm9wKSkgKyANCiAgIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBjb2xvcj0iI0FBMTg1QUZGIiwgZmlsbD0iI0Y4RDdCRkZGIiwgc2U9VFJVRSkrDQogICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9U2l0ZS5PcmlnLCBzaGFwZT1HZW5vdHlwZSksc2l6ZT1wb2ludC5zeikrDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9T3JpZy5jb2xvcnMubykrDQogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9R2Vuby5zaGFwZXMubykrDQogICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9ZXhwcmVzc2lvbihwYXN0ZSgnR3Jvd3RoIFJhdGUgKGNtIGRheSdeLTEqIikiKSksIA0KICAgICAgIHk9IlN5bWJpb250IFJldGVudGlvbiIsIA0KICAgICAgIGNvbG91cj0iU2l0ZSBPcmlnaW4iKSsNCiAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDAuMDcsIHkgPSAwLjEsIGxhYmVsPWV4cHJlc3Npb24oaXRhbGljKHBhc3RlKHJbU10sICIgPSAtMC41NTIsIHAgPSAwLjA2NyIpKSksIHNpemU9c2lnLnN6LCBoanVzdCA9IDApOyBUUDMuNF9UTEVfU3ltLnBsb3QNCmBgYA0KDQoNCiMjIyMgQ2hsb3JvcGh5bGwgUmV0ZW50aW9uDQoNCmBgYHtyfQ0KY29yLnRlc3QoVFAzLjRfUGVyZl9TZXQkVExFX2NtLmRheSwgVFAzLjRfUGVyZl9TZXQkQ2hsLnByb3AsIG1ldGhvZD0ic3BlYXJtYW4iKQ0KYGBgDQoNCg0KYGBge3IgUGxvdCBHcm93dGggdnMgQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIFQzNH0NClRQMy40X1RMRV9DaGwucGxvdDwtZ2dwbG90KFRQMy40X1BlcmZfU2V0LCBhZXMoeD1UTEVfY20uZGF5LCB5PUNobC5wcm9wKSkgKyANCiAgIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBjb2xvcj0iI0FBMTg1QUZGIiwgZmlsbD0iI0Y4RDdCRkZGIiwgc2U9VFJVRSkrDQogICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9U2l0ZS5PcmlnLCBzaGFwZT1HZW5vdHlwZSksc2l6ZT1wb2ludC5zeikrDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9T3JpZy5jb2xvcnMubykrDQogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9R2Vuby5zaGFwZXMubykrDQogICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIikpKw0KICBsYWJzKHg9ZXhwcmVzc2lvbihwYXN0ZSgnR3Jvd3RoIFJhdGUgKGNtIGRheSdeLTEqIikiKSksIA0KICAgICAgIHk9IkNobG9yb3BoeWxsIFJldGVudGlvbiIsIA0KICAgICAgIGNvbG91cj0iU2l0ZSBPcmlnaW4iKSsNCiAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDAuMDcsIHkgPSAwLjA2NSwgbGFiZWw9ZXhwcmVzc2lvbihpdGFsaWMocGFzdGUocltTXSwgIiA9IDAuMzI3LCBwID0gMC4zMjciKSkpLCBzaXplPXNpZy5zeiwgaGp1c3QgPSAwKTsgVFAzLjRfVExFX0NobC5wbG90DQpgYGANCg0KDQojIyMjIEZ2Rm0gUmV0ZW50aW9uDQoNCmBgYHtyfQ0KY29yLnRlc3QoVFAzLjRfUGVyZl9TZXQkVExFX2NtLmRheSwgVFAzLjRfUGVyZl9TZXQkUEFNLnByb3AsIG1ldGhvZD0ic3BlYXJtYW4iKQ0KYGBgDQoNCg0KYGBge3IgUGxvdCBHcm93dGggdnMgRnZGbSBSZXRlbnRpb24gVDM0fQ0KVFAzLjRfVExFX1BBTS5wbG90PC1nZ3Bsb3QoVFAzLjRfUGVyZl9TZXQsIGFlcyh4PVRMRV9jbS5kYXksIHk9UEFNLnByb3ApKSArIA0KICAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIGNvbG9yPSIjQUExODVBRkYiLCBmaWxsPSIjRjhEN0JGRkYiLCBzZT1UUlVFKSsNCiAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1TaXRlLk9yaWcsIHNoYXBlPUdlbm90eXBlKSxzaXplPXBvaW50LnN6KSsNCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1PcmlnLmNvbG9ycy5vKSsNCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1HZW5vLnNoYXBlcy5vKSsNCiAgIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSkrDQogIGxhYnMoeD1leHByZXNzaW9uKHBhc3RlKCdHcm93dGggUmF0ZSAoY20gZGF5J14tMSoiKSIpKSwgDQogICAgICAgeT0iUGhvdG8uIEVmZmljLiBSZXRlbnRpb24iLCANCiAgICAgICBjb2xvdXI9IlNpdGUgT3JpZ2luIikrDQogICBhbm5vdGF0ZSgidGV4dCIsIHggPSAwLjA3LCB5ID0gMC41LCBsYWJlbD1leHByZXNzaW9uKGJvbGRpdGFsaWMocGFzdGUocltTXSwgIiA9IC0wLjc0OCwgcCA9IDAuMDA3IikpKSwgc2l6ZT1zaWcuc3osIGhqdXN0ID0gMCk7IFRQMy40X1RMRV9QQU0ucGxvdA0KYGBgDQoNCg0KIyBGaWd1cmVzDQoNCiMjIyBGaWd1cmUgNCBQZXJmb3JtYW5jZSBFZmZlY3QgU2l6ZXMNCg0KIyMjIyBBZGp1c3QgZm9yIFBhbmVsDQpgYGB7cn0NClBlcmYuU2l0ZS5PcmlnLkVTLnBsb3Q8LVBlcmYuU2l0ZS5PcmlnLkVTLnBsb3QrIGxhYnMoeD0iIikNCmBgYA0KDQoNCiMjIyMgRmlndXJlIDQNCmBgYHtyfQ0KIyNDcmVhdGUgUGFuZWwNClBlcmYuRVNfZmlnPC1wbG90X2dyaWQoUGVyZi5TaXRlLk9yaWcuRVMucGxvdCwgUGVyZi5PcmlnLkVTLnBsb3QsIA0KICAgICAgICAgICAgICAgICAgICByZWxfd2lkdGhzPTEsIHJlbF9oZWlnaHRzID0gMSwNCiAgICAgICAgICAgICAgICAgICAgbnJvdz0yLCBuY29sPTEsIGJ5cm93PVQsIGxhYmVscyA9IGMoIkEiLCAiQiIpLCANCiAgICAgICAgICAgICAgICAgICAgbGFiZWxfc2l6ZT1wYW5lbC5sYWIuc3opDQoNCiMjU2F2ZSBGaWd1cmUNCmdnc2F2ZShmaWxlbmFtZT0iRmlndXJlcy8wM19QZXJmb3JtYW5jZS9GaWc0X1BlcmZvcm1hbmNlRWZmZWN0U2l6ZXMucG5nIiwgcGxvdD1QZXJmLkVTX2ZpZywgZHBpPTMwMCwgd2lkdGg9MTIsIGhlaWdodD05LCB1bml0cz0iaW4iKQ0KDQpgYGANCg0KDQojIyMgRmlndXJlIDUgR3Jvd3RoIHZzIFRvbGVyYW5jZQ0KDQojIyMjIEFkanVzdCBGaWd1cmVzIGZvciBQYW5lbA0KYGBge3J9DQojI1RpbWVwb2ludCAxIHRvIDINClRQMS4yX1RMRV9QQU0ucGxvdDwtVFAxLjJfVExFX1BBTS5wbG90ICsgZ2d0aXRsZSgiUGhvdG8uIEVmZmljLiIpKyBsYWJzKHg9TlVMTCwgeSA9ICJUb2xlcmFuY2UgKFJldGVudGlvbikiKSsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvdXI9ImJsYWNrIiwgc2l6ZT1wYW5lbC5sYWIuc3osIGhqdXN0PTAuNSksIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNClRQMS4yX1RMRV9TeW0ucGxvdDwtIFRQMS4yX1RMRV9TeW0ucGxvdCArIGdndGl0bGUoIlN5bWJpb250cyIpKyBsYWJzKHg9TlVMTCwgeSA9IE5VTEwpKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG91cj0iYmxhY2siLCBzaXplPXBhbmVsLmxhYi5zeiwgaGp1c3Q9MC41KSkgKyB5bGltKC0uMTUsIC44KQ0KDQoNCiMjVGltZXBvaW50IDMgdG8gNA0KVFAzLjRfVExFX1BBTS5wbG90PC1UUDMuNF9UTEVfUEFNLnBsb3QgKyBsYWJzKHkgPSAiVG9sZXJhbmNlIChSZXRlbnRpb24pIikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KDQpUUDMuNF9UTEVfU3ltLnBsb3Q8LVRQMy40X1RMRV9TeW0ucGxvdCArIGxhYnMoeSA9IE5VTEwpDQoNCmBgYA0KDQoNCiMjIyMgRmlndXJlIDUNCmBgYHtyfQ0KIyNDcmVhdGUgUGFuZWwNClRyYWRlT2ZmX2ZpZzwtcGxvdF9ncmlkKFRQMS4yX1RMRV9QQU0ucGxvdCwgVFAxLjJfVExFX1N5bS5wbG90LA0KICAgICAgICAgICAgICAgICAgICAgIFRQMy40X1RMRV9QQU0ucGxvdCwgVFAzLjRfVExFX1N5bS5wbG90LA0KICAgICAgICAgICAgICAgICAgICByZWxfd2lkdGhzPWMoLjc1LCAxKSwgcmVsX2hlaWdodHMgPSBjKDEsIC45OCksDQogICAgICAgICAgICAgICAgICAgIG5yb3c9MiwgbmNvbD0yLCBieXJvdz1ULCANCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQSIsICJCIiwgIkMiLCAiRCIpLCANCiAgICAgICAgICAgICAgICAgICAgbGFiZWxfc2l6ZT1wYW5lbC5sYWIuc3opDQoNCiMjU2F2ZSBGaWd1cmUNCmdnc2F2ZShmaWxlbmFtZT0iRmlndXJlcy8wM19QZXJmb3JtYW5jZS9GaWc1X1RyYWRlT2ZmLnBuZyIsIHBsb3Q9VHJhZGVPZmZfZmlnLCBkcGk9MzAwLCB3aWR0aD04LCBoZWlnaHQ9OCwgdW5pdHM9ImluIikNCg0KYGBgDQoNCg0KIyMjIEZpZ3VyZSBTNSBHcm93dGgNCg0KIyMjIyBBZGp1c3QgRmlndXJlcyBmb3IgUGFuZWwNCmBgYHtyfQ0KIyNUUCAxIHRvIFRQIDINClRQMS4yX0dyb3d0aC5wbG90PC1UUDEuMl9Hcm93dGgucGxvdCsgZ2d0aXRsZSgiVFAxIHRvIFRQMiIpKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG91cj0iYmxhY2siLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPXBhbmVsLmxhYi5zeiwgaGp1c3Q9MC41KSwgDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj1jKDAuMjUsIDAuODUpLCBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIikrDQogIGxhYnMoY29sb3VyPU5VTEwpKw0KICBndWlkZXMoY29sb3I9Z3VpZGVfbGVnZW5kKG5yb3c9MiwgYnlyb3c9RkFMU0UpKSANCg0KDQojI1RQIDMgdG8gVFAgNA0KVFAzLjRfR3Jvd3RoLnBsb3Q8LVRQMy40X0dyb3d0aC5wbG90KyBnZ3RpdGxlKCJUUDMgdG8gVFA0IikrDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3VyPSJibGFjayIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9cGFuZWwubGFiLnN6LCBoanVzdD0wLjUpLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KYGBgDQoNCg0KIyMjIyBGaWd1cmUgUzUNCmBgYHtyfQ0KIyNDcmVhdGUgUGFuZWwNCkdyb3d0aF9maWc8LXBsb3RfZ3JpZChUUDEuMl9Hcm93dGgucGxvdCwgVFAzLjRfR3Jvd3RoLnBsb3QsIA0KICAgICAgICAgICAgICAgICAgICByZWxfd2lkdGhzPTEsIHJlbF9oZWlnaHRzID0gMSwNCiAgICAgICAgICAgICAgICAgICAgbnJvdz0xLCBuY29sPTIsIGJ5cm93PVQsIGxhYmVscyA9IGMoIkEiLCAiQiIpLCANCiAgICAgICAgICAgICAgICAgICAgbGFiZWxfc2l6ZT1wYW5lbC5sYWIuc3opDQoNCiMjU2F2ZSBGaWd1cmUNCmdnc2F2ZShmaWxlbmFtZT0iRmlndXJlcy8wM19QZXJmb3JtYW5jZS9GaWdTNV9Hcm93dGgucG5nIiwgcGxvdD1Hcm93dGhfZmlnLCBkcGk9MzAwLCB3aWR0aD0xMCwgaGVpZ2h0PTQuNSwgdW5pdHM9ImluIikNCg0KYGBgDQoNCg0KIyMjIEZpZ3VyZSBTNiBJbml0aWFsIEhlYXQgQXNzYXkNCg0KIyMjIyBBZGp1c3QgRmlndXJlcyBmb3IgUGFuZWwNCmBgYHtyfQ0KIyNGdkZtDQpJTl9QQU0ucGxvdDwtSU5fUEFNLnBsb3QgKyBsYWJzKHg9IiIsIHk9IkZ2L0ZtIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIHlsaW0oMC41LCAwLjY1NSkNCg0KSU5fVG9sUEFNLnBsb3Q8LUlOX1RvbFBBTS5wbG90ICsgbGFicyh4PSIiLCB5PSJSZXRlbnRpb24iKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIHlsaW0oMC43NSwgMSkNCg0KIyNTeW1iaW9udHMNCklOX1N5bS5wbG90PC1JTl9TeW0ucGxvdCArIGxhYnMoeD0iIiwgeT0iU3ltYmlvbnRzIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIHlsaW0oMCwxKQ0KDQpJTl9Ub2xTeW0ucGxvdDwtSU5fVG9sU3ltLnBsb3QgKyBsYWJzKHg9IiIsIHk9IlJldGVudGlvbiIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsgeWxpbSguMjUsIC43NSkNCg0KIyNDaGxvcm9waHlsbA0KSU5fQ2hsLnBsb3Q8LUlOX0NobC5wbG90ICsgbGFicyh4PSJTaXRlIGFuZCBUcmVhdG1lbnQiLCB5PSJDaGxvcm9waHlsbCIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsgeWxpbSgwLDEuMjUpDQoNCklOX1RvbENobC5wbG90PC1JTl9Ub2xDaGwucGxvdCArIGxhYnMoeD0iU2l0ZSIsIHk9IlJldGVudGlvbiIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsgeWxpbSgwLCAwLjI1KQ0KDQpgYGANCg0KDQojIyMjIEZpZ3VyZSBTNg0KYGBge3J9DQojI0NyZWF0ZSBQYW5lbA0KSU5fSGVhdEFzc2F5X2ZpZzwtcGxvdF9ncmlkKElOX1BBTS5wbG90LCBJTl9Ub2xQQU0ucGxvdCwgDQogICAgICAgICAgICAgICAgICAgICAgSU5fU3ltLnBsb3QsIElOX1RvbFN5bS5wbG90LA0KICAgICAgICAgICAgICAgICAgICAgIElOX0NobC5wbG90LCBJTl9Ub2xDaGwucGxvdCwNCiAgICAgICAgICAgICAgICAgICAgcmVsX3dpZHRocz1jKDEsIDAuNzUpLCANCiAgICAgICAgICAgICAgICAgICAgcmVsX2hlaWdodHMgPSBjKDEsIDEsIDEpLA0KICAgICAgICAgICAgICAgICAgICBucm93PTMsIG5jb2w9MiwgYnlyb3c9VCwgDQogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkEiLCAiQiIsICJDIiwgIkQiLCAiRSIsICJGIiksIA0KICAgICAgICAgICAgICAgICAgICBsYWJlbF9zaXplPXBhbmVsLmxhYi5zeikNCg0KIyNTYXZlIEZpZ3VyZQ0KZ2dzYXZlKGZpbGVuYW1lPSJGaWd1cmVzLzAzX1BlcmZvcm1hbmNlL0ZpZ1M2X0luaXRpYWxIZWF0QXNzYXkucG5nIiwgcGxvdD1JTl9IZWF0QXNzYXlfZmlnLCBkcGk9MzAwLCB3aWR0aD04LCBoZWlnaHQ9MTEsIHVuaXRzPSJpbiIpDQoNCmBgYA0KDQoNCiMjIyBGaWd1cmUgUzcgVGhlcm1hbCBUb2xlcmFuY2UNCg0KIyMjIyBBZGp1c3QgRmlndXJlcyBmb3IgUGFuZWwNCmBgYHtyfQ0KIyNGdkZtIFJldGVudGlvbg0KVFAxX1RvbFBBTS5wbG90PC1UUDFfVG9sUEFNLnBsb3QgKyBnZ3RpdGxlKCJUUDEiKSsgDQogIGxhYnMoeD1OVUxMLCB5PSJQaG90by4gRWZmaWMuIFJldGVudGlvbiIsIGNvbG91cj1OVUxMKSsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvdXI9ImJsYWNrIiwgc2l6ZT1wYW5lbC5sYWIuc3osIGZhY2U9ImJvbGQiLCBoanVzdD0wLjUpLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPWMoMC41LCAwLjE1KSwgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIpKw0KICBndWlkZXMoY29sb3I9Z3VpZGVfbGVnZW5kKG5yb3c9MiwgYnlyb3c9RkFMU0UpKQ0KDQpUUDJfVG9sUEFNLnBsb3Q8LVRQMl9Ub2xQQU0ucGxvdCsgZ2d0aXRsZSgiVFAyIikrIGxhYnMoeD1OVUxMLCB5PU5VTEwpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvdXI9ImJsYWNrIiwgc2l6ZT1wYW5lbC5sYWIuc3osIGZhY2U9ImJvbGQiLCBoanVzdD0wLjUpLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KVFAzX1RvbFBBTS5wbG90PC1UUDNfVG9sUEFNLnBsb3QrIGdndGl0bGUoIlRQMyIpKyBsYWJzKHg9TlVMTCwgeT1OVUxMKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3VyPSJibGFjayIsIHNpemU9cGFuZWwubGFiLnN6LCBmYWNlPSJib2xkIiwgaGp1c3Q9MC41KSwgDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNClRQNF9Ub2xQQU0ucGxvdDwtVFA0X1RvbFBBTS5wbG90KyBnZ3RpdGxlKCJUUDQiKSsgbGFicyh4PU5VTEwsIHk9TlVMTCkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG91cj0iYmxhY2siLCBzaXplPXBhbmVsLmxhYi5zeiwgZmFjZT0iYm9sZCIsIGhqdXN0PTAuNSksIA0KICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KDQoNCiMjU3ltYmlvbnQgUmV0ZW50aW9uDQpUUDFfVG9sU3ltLnBsb3Q8LSBUUDFfVG9sU3ltLnBsb3QgKyBsYWJzKHg9TlVMTCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KDQpUUDJfVG9sU3ltLnBsb3Q8LSBUUDJfVG9sU3ltLnBsb3QgKyBsYWJzKHg9TlVMTCwgeT1OVUxMKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNClRQM19Ub2xTeW0ucGxvdDwtIFRQM19Ub2xTeW0ucGxvdCArIGxhYnMoeD1OVUxMLCB5PU5VTEwpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KVFA0X1RvbFN5bS5wbG90PC0gVFA0X1RvbFN5bS5wbG90ICsgbGFicyh4PU5VTEwsIHk9TlVMTCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KDQoNCiMjQ2hsb3JvcGh5bGwgUmV0ZW50aW9uDQpUUDFfVG9sQ2hsLnBsb3Q8LVRQMV9Ub2xDaGwucGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNClRQMl9Ub2xDaGwucGxvdDwtVFAyX1RvbENobC5wbG90ICsgbGFicyh5PU5VTEwpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KVFAzX1RvbENobC5wbG90PC1UUDNfVG9sQ2hsLnBsb3QgKyBsYWJzKHk9TlVMTCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KDQpUUDRfVG9sQ2hsLnBsb3Q8LVRQNF9Ub2xDaGwucGxvdCArIGxhYnMoeT1OVUxMKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNCmBgYA0KDQoNCiMjIyMgRmlndXJlIFM3DQpgYGB7cn0NCiMjQ3JlYXRlIFBhbmVsDQpUb2xlcmFuY2VfZmlnPC1wbG90X2dyaWQoVFAxX1RvbFBBTS5wbG90LCBUUDJfVG9sUEFNLnBsb3QsIA0KICAgICAgICAgICAgICAgICAgICAgIFRQM19Ub2xQQU0ucGxvdCwgVFA0X1RvbFBBTS5wbG90LCANCiAgICAgICAgICAgICAgICAgICAgICBUUDFfVG9sU3ltLnBsb3QsIFRQMl9Ub2xTeW0ucGxvdCwgDQogICAgICAgICAgICAgICAgICAgICAgVFAzX1RvbFN5bS5wbG90LCBUUDRfVG9sU3ltLnBsb3QsIA0KICAgICAgICAgICAgICAgICAgICAgIFRQMV9Ub2xDaGwucGxvdCwgVFAyX1RvbENobC5wbG90LCANCiAgICAgICAgICAgICAgICAgICAgICBUUDNfVG9sQ2hsLnBsb3QsIFRQNF9Ub2xDaGwucGxvdCwgDQogICAgICAgICAgICAgICAgICAgIHJlbF93aWR0aHM9MSwgcmVsX2hlaWdodHMgPSAxLA0KICAgICAgICAgICAgICAgICAgICBucm93PTMsIG5jb2w9NCwgYnlyb3c9VCwgbGFiZWxzID0gTlVMTCkNCg0KIyNTYXZlIEZpZ3VyZQ0KZ2dzYXZlKGZpbGVuYW1lPSJGaWd1cmVzLzAzX1BlcmZvcm1hbmNlL0ZpZ1M3X1RvbGVyYW5jZS5wbmciLCBwbG90PVRvbGVyYW5jZV9maWcsIGRwaT0zMDAsIHdpZHRoPTE0LCBoZWlnaHQ9MTIsIHVuaXRzPSJpbiIpDQoNCmBgYA0KDQoNCiMgVGFibGVzDQoNCiMjIyBUYWJsZSBTNiBQZXJmb3JtYW5jZSBMTQ0KYGBge3J9DQojI1NhdmUgUmVzdWx0cyBUYWJsZQ0KVGFibGVTNl9QZXJmLkxNPC1QZXJmLnJlcw0KICANCiMjT3JnYW5pemUNCm5hbWVzKFRhYmxlUzZfUGVyZi5MTSkNClRhYmxlUzZfUGVyZi5MTTwtVGFibGVTNl9QZXJmLkxNICU+JSBkcGx5cjo6cmVuYW1lKFNFID0gU3RkLi5FcnJvciwgREYgPSBkZiwgdCA9IHQudmFsdWUsIFRpbWVwb2ludCA9IFRpbWVQKQ0KVGFibGVTNl9QZXJmLkxNPC1UYWJsZVM2X1BlcmYuTE1bLGMoIlRpbWVwb2ludCIsICJSZXNwb25zZSIsICJQcmVkaWN0b3IiLCAiRXN0aW1hdGUiLCAiU0UiLCAiREYiLCAidCIsICJwIiwgIkV0YVNxIildDQoNCiNSb3VuZCB0byAzIGRpZ2l0cw0KVGFibGVTNl9QZXJmLkxNJEVzdGltYXRlPC1yb3VuZChUYWJsZVM2X1BlcmYuTE0kRXN0aW1hdGUsIDMpDQpUYWJsZVM2X1BlcmYuTE0kU0U8LXJvdW5kKFRhYmxlUzZfUGVyZi5MTSRTRSwgMykNClRhYmxlUzZfUGVyZi5MTSR0PC1yb3VuZChUYWJsZVM2X1BlcmYuTE0kdCwgMykNClRhYmxlUzZfUGVyZi5MTSRwPC1yb3VuZChUYWJsZVM2X1BlcmYuTE0kcCwgMykNClRhYmxlUzZfUGVyZi5MTSRFdGFTcTwtcm91bmQoVGFibGVTNl9QZXJmLkxNJEV0YVNxLCAzKQ0KDQojSW50ZWdlcg0KVGFibGVTNl9QZXJmLkxNJERGPC1yb3VuZChUYWJsZVM2X1BlcmYuTE0kREYsIDApDQoNCiMjV3JpdGUgT3V0IFRhYmxlDQp3cml0ZS5jc3YoVGFibGVTNl9QZXJmLkxNLCAiVGFibGVzL1RhYmxlUzZfUGVyZm9ybWFuY2VfTE1fUmVzdWx0cy5jc3YiLCByb3cubmFtZXM9RkFMU0UpDQoNCmBgYA0KDQoNCiMjIyBUYWJsZSBTNyBQZXJmb3JtYW5jZSBQYWlyd2lzZQ0KYGBge3J9DQojI1NhdmUgUmVzdWx0cyBUYWJsZQ0KVGFibGVTN19QZXJmLnBhaXI8LVBlcmYucGFpci5yZXMNCg0KIyNPcmdhbml6ZQ0KbmFtZXMoVGFibGVTN19QZXJmLnBhaXIpDQpUYWJsZVM3X1BlcmYucGFpcjwtVGFibGVTN19QZXJmLnBhaXIgJT4lIGRwbHlyOjpyZW5hbWUoVGltZXBvaW50ID0gVGltZVAsIENvbnRyYXN0ID1jb250cmFzdCwgRXN0aW1hdGUgPSBlc3RpbWF0ZSwgREYgPSBkZiwgdCA9IHQucmF0aW8sIHAgPSBwLnZhbHVlLCBFZmZlY3RTaXplID0gZWZmZWN0LnNpemUsIEVmZmVjdFNpemUuU0UgPSBTRS5lcykNClRhYmxlUzdfUGVyZi5wYWlyPC1UYWJsZVM3X1BlcmYucGFpclssYygiVGltZXBvaW50IiwgIlJlc3BvbnNlIiwgIlNpdGUiLCAiQ29udHJhc3QiLCAiRXN0aW1hdGUiLCAiU0UiLCAiREYiLCAidCIsICJwIiwgIkVmZmVjdFNpemUiLCAiRWZmZWN0U2l6ZS5TRSIpXQ0KDQojUm91bmQgdG8gMyBkaWdpdHMNClRhYmxlUzdfUGVyZi5wYWlyJEVzdGltYXRlPC1yb3VuZChUYWJsZVM3X1BlcmYucGFpciRFc3RpbWF0ZSwgMykNClRhYmxlUzdfUGVyZi5wYWlyJFNFPC1yb3VuZChUYWJsZVM3X1BlcmYucGFpciRTRSwgMykNClRhYmxlUzdfUGVyZi5wYWlyJHQ8LXJvdW5kKFRhYmxlUzdfUGVyZi5wYWlyJHQsIDMpDQpUYWJsZVM3X1BlcmYucGFpciRwPC1yb3VuZChUYWJsZVM3X1BlcmYucGFpciRwLCAzKQ0KVGFibGVTN19QZXJmLnBhaXIkRWZmZWN0U2l6ZTwtcm91bmQoVGFibGVTN19QZXJmLnBhaXIkRWZmZWN0U2l6ZSwgMykNClRhYmxlUzdfUGVyZi5wYWlyJEVmZmVjdFNpemUuU0U8LXJvdW5kKFRhYmxlUzdfUGVyZi5wYWlyJEVmZmVjdFNpemUuU0UsIDMpDQoNCiNJbnRlZ2VyDQpUYWJsZVM3X1BlcmYucGFpciRERjwtcm91bmQoVGFibGVTN19QZXJmLnBhaXIkREYsIDApDQoNCiMjV3JpdGUgT3V0IFRhYmxlDQp3cml0ZS5jc3YoVGFibGVTN19QZXJmLnBhaXIsICJUYWJsZXMvVGFibGVTN19QZXJmb3JtYW5jZV9QYWlyd2lzZV9SZXN1bHRzLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkNCg0KYGBgDQoNCg0KIyMjIFRhYmxlIFM4IEluaXRpYWwgSGVhdCBBc3NheSBMTQ0KYGBge3J9DQojI0NvbWJpbmUgUmVzdWx0cyBUYWJsZXMNClRhYmxlUzhfSU5fVG9sZXJhbmNlPC1kYXRhLmZyYW1lKHJiaW5kKFBBTV9JTi5yZXMsIFN5bV9JTi5yZXMsIENobF9JTi5yZXMpKQ0KDQojI09yZ2FuaXplDQpuYW1lcyhUYWJsZVM4X0lOX1RvbGVyYW5jZSkNClRhYmxlUzhfSU5fVG9sZXJhbmNlPC1UYWJsZVM4X0lOX1RvbGVyYW5jZSAlPiUgZHBseXI6OnJlbmFtZShFc3RpbWF0ZSA9IGVzdGltYXRlLCBERiA9IGRmLCB0ID0gdC5yYXRpbywgcCA9IHAudmFsdWUsIEVmZmVjdFNpemUgPSBFdGFTcSkNClRhYmxlUzhfSU5fVG9sZXJhbmNlPC1UYWJsZVM4X0lOX1RvbGVyYW5jZVssYygiUmVzcG9uc2UiLCAiUHJlZGljdG9yIiwgIkVzdGltYXRlIiwgIlNFIiwgIkRGIiwgInQiLCAicCIsICJFZmZlY3RTaXplIildDQoNCiNSb3VuZCB0byAzIGRpZ2l0cw0KVGFibGVTOF9JTl9Ub2xlcmFuY2UkRXN0aW1hdGU8LXJvdW5kKFRhYmxlUzhfSU5fVG9sZXJhbmNlJEVzdGltYXRlLCAzKQ0KVGFibGVTOF9JTl9Ub2xlcmFuY2UkU0U8LXJvdW5kKFRhYmxlUzhfSU5fVG9sZXJhbmNlJFNFLCAzKQ0KVGFibGVTOF9JTl9Ub2xlcmFuY2UkdDwtcm91bmQoVGFibGVTOF9JTl9Ub2xlcmFuY2UkdCwgMykNClRhYmxlUzhfSU5fVG9sZXJhbmNlJHA8LXJvdW5kKFRhYmxlUzhfSU5fVG9sZXJhbmNlJHAsIDMpDQpUYWJsZVM4X0lOX1RvbGVyYW5jZSRFZmZlY3RTaXplPC1yb3VuZChUYWJsZVM4X0lOX1RvbGVyYW5jZSRFZmZlY3RTaXplLCAzKQ0KDQojSW50ZWdlcg0KVGFibGVTOF9JTl9Ub2xlcmFuY2UkREY8LXJvdW5kKFRhYmxlUzhfSU5fVG9sZXJhbmNlJERGLCAwKQ0KDQojI1dyaXRlIE91dCBUYWJsZQ0Kd3JpdGUuY3N2KFRhYmxlUzhfSU5fVG9sZXJhbmNlLCAiVGFibGVzL1RhYmxlUzhfSW5pdGlhbF9Ub2xlcmFuY2VfTE1fUmVzdWx0cy5jc3YiLCByb3cubmFtZXM9RkFMU0UpDQoNCmBgYA0KDQo=